In this short guide, you'll see the difference between dot notation and square bracket notation in Python and Pandas.

Here you can find the short answer:

(1) Dot notation for attributes

df.column_name
obj.attribute

(2) Square bracket notation for keys

df['column_name']
dict['key']

(3) When you must use brackets

df['column name with spaces']
df['2024']  # Starts with number

So let's see when to use dot notation versus square bracket notation in Python.

Suppose you have a DataFrame like:

Name Age Salary
Alice 28 75000
Bob 35 85000

1: Dot notation - Simple attribute access

Let's start with dot notation, which provides clean and readable syntax for accessing object attributes and DataFrame columns:

import pandas as pd

df = pd.DataFrame({
    'name': ['Apple Inc', 'Microsoft Corp', 'Google LLC'],
    'revenue': [394000, 211000, 307000],
    'employees': [164000, 221000, 190000]
})

print(df.name)
print(df.revenue.mean())
print(df.employees.max())

result will be:

0       Apple Inc
1    Microsoft Corp
2      Google LLC
Name: name, dtype: object

304000.0
221000

Dot notation is the preferred style when:

  • Column names are valid Python identifiers (no spaces, don't start with numbers)
  • You want cleaner, more readable code
  • Using IDE autocomplete features

What if you try to use dot notation with invalid column names? You'll get an error:

df.Apple Inc  # SyntaxError - spaces not allowed
df.2024_data  # SyntaxError - starts with number

2: Square bracket notation - Universal access method

Square bracket notation is the universal method that works with any column name or dictionary key, regardless of naming conventions:

import pandas as pd

df = pd.DataFrame({
    'Company Name': ['Amazon', 'Tesla', 'Meta'],
    '2024 Revenue': [575000, 96000, 134000],
    'Market Cap': [1800000, 850000, 950000],
    'P/E Ratio': [45.2, 68.9, 28.4]
})

print(df['Company Name'])
print(f"Average 2024 Revenue: ${df['2024 Revenue'].mean():,.0f}")
print(f"Highest Market Cap: ${df['Market Cap'].max():,.0f}")
print(f"Average P/E: {df['P/E Ratio'].mean():.1f}")

result:

0    Amazon
1     Tesla
2      Meta
Name: Company Name, dtype: object

Average 2024 Revenue: $268,333
Highest Market Cap: $1,800,000
Average P/E: 47.5

Square bracket notation is required when:

  • Column names contain spaces ('Company Name')
  • Column names start with numbers ('2024 Revenue')
  • Column names contain special characters ('P/E Ratio')
  • Accessing dictionary keys with any string
  • Column name stored in a variable

3: Working with dictionaries - Square brackets required

For Python dictionaries, you must use square bracket notation to access values:

company_data = {
    'name': 'NVIDIA Corporation',
    'ticker': 'NVDA',
    'sector': 'Technology',
    'market_cap': 1200000,
    '52_week_high': 505.89
}

print(f"Company: {company_data['name']}")
print(f"Ticker: {company_data['ticker']}")
print(f"52-Week High: ${company_data['52_week_high']}")

try:
    print(company_data.name)
except AttributeError as e:
    print(f"Error with dot notation: {e}")

result:

Company: NVIDIA Corporation
Ticker: NVDA
52-Week High: $505.89
Error with dot notation: 'dict' object has no attribute 'name'

Key point: Standard Python dictionaries don't support dot notation. Only special objects like pandas DataFrames allow both syntaxes.

4: Dynamic column access with variables

Square bracket notation is essential when column names are stored in variables or generated dynamically:

import pandas as pd

df = pd.DataFrame({
    'AAPL': [185.64, 186.89, 185.92],
    'MSFT': [372.55, 375.23, 373.89],
    'GOOGL': [145.23, 146.78, 145.67]
})

user_stock = 'AAPL'
print(f"{user_stock} prices:")
print(df[user_stock])

for ticker in ['AAPL', 'MSFT', 'GOOGL']:
    avg_price = df[ticker].mean()
    print(f"{ticker} average: ${avg_price:.2f}")

result:

AAPL prices:
0    185.64
1    186.89
2    185.92
Name: AAPL, dtype: float64

AAPL average: $186.15
MSFT average: $373.89
GOOGL average: $145.89

You cannot use dot notation with variables: df.user_stock would look for a column literally named "user_stock".

5: Pandas-specific considerations

Pandas DataFrames support both notations, but with important differences in behavior and method conflicts:

import pandas as pd

df = pd.DataFrame({
    'product': ['iPhone 15', 'Galaxy S24', 'Pixel 8'],
    'price': [999, 899, 699],
    'count': [1000, 850, 650],
    'sum': [999000, 764150, 454350]
})

print("Using dot notation:")
print(df.price.mean())

print("\nUsing square brackets:")
print(df['price'].mean())

print("\nConflict with DataFrame method 'count':")
print(type(df.count))
print(type(df['count']))

print("\nAccessing actual 'count' column:")
print(df['count'].head())

print("\nConflict with DataFrame method 'sum':")
try:
    print(df.sum.mean())
except TypeError as e:
    print(f"Error: {e}")

print("\nCorrect way:")
print(df['sum'].mean())

result:

Using dot notation:
865.6666666666666

Using square brackets:
865.6666666666666

Conflict with DataFrame method 'count':
<class 'method'>
<class 'pandas.core.series.Series'>

Accessing actual 'count' column:
0    1000
1     850
2     650
Name: count, dtype: int64

Conflict with DataFrame method 'sum':
Error: 'builtin_function_or_method' object has no attribute 'mean'

Correct way:
739166.6666666666667

Reserved pandas methods that conflict with column names:

  • count, sum, mean, max, min, std, var
  • head, tail, describe, info, shape
  • index, columns, values, dtypes
  • sort, drop, merge, join, fillna

Best practice: Always use square bracket notation for columns that might conflict with pandas methods.

6: Creating new columns - Syntax differences

When creating new columns, both notations work, but square brackets are more reliable:

import pandas as pd

df = pd.DataFrame({
    'company': ['Apple', 'Microsoft', 'Google'],
    'revenue': [394000, 211000, 307000],
    'expenses': [276000, 138000, 198000]
})

df['profit'] = df['revenue'] - df['expenses']

df.margin = (df['profit'] / df['revenue']) * 100

df['profit_margin'] = df.margin

print(df[['company', 'revenue', 'profit', 'profit_margin']])

result:

     company  revenue  profit  profit_margin
0      Apple   394000  118000      29.949239
1  Microsoft   211000   73000      34.597156
2     Google   307000  109000      35.504886

Warning: Creating columns with dot notation (df.new_col = ...) can sometimes create Python attributes instead of DataFrame columns, especially in certain contexts. Always use square brackets for column creation in production code.

7: Common errors and how to fix them

Understanding common errors helps avoid pitfalls when choosing between dot and bracket notation:

Error 1: AttributeError with dot notation

import pandas as pd

df = pd.DataFrame({
    'Customer Name': ['Apple Inc', 'Microsoft Corp'],
    'Order Value': [15000, 22000]
})

try:
    print(df.Customer Name)
except SyntaxError:
    print("SyntaxError: invalid syntax")

try:
    print(df.customer_name)
except AttributeError as e:
    print(f"AttributeError: {e}")

print("\nCorrect way:")
print(df['Customer Name'])

result:

SyntaxError: invalid syntax
AttributeError: 'DataFrame' object has no attribute 'customer_name'

Correct way:
0       Apple Inc
1    Microsoft Corp
Name: Customer Name, dtype: object

Error 2: KeyError with square brackets

import pandas as pd

df = pd.DataFrame({
    'product': ['iPhone', 'iPad'],
    'price': [999, 599]
})

try:
    print(df['Product'])
except KeyError as e:
    print(f"KeyError: {e}")

print("\nColumn names are case-sensitive:")
print(df.columns.tolist())

print("\nCorrect way:")
print(df['product'])

result:

KeyError: 'Product'

Column names are case-sensitive:
['product', 'price']

Correct way:
0    iPhone
1      iPad
Name: product, dtype: object

Error 3: Method confusion with dot notation

import pandas as pd

df = pd.DataFrame({
    'name': ['Tesla', 'Rivian'],
    'count': [500000, 50000],
    'max': [1000000, 100000]
})

print("Trying to access 'count' column with dot notation:")
print(f"Type: {type(df.count)}")

print("\nCorrect way to access 'count' column:")
print(df['count'])

print("\nTrying to access 'max' column with dot notation:")
print(f"Type: {type(df.max)}")

print("\nCorrect way to access 'max' column:")
print(df['max'])

result:

Trying to access 'count' column with dot notation:
Type: <class 'method'>

Correct way to access 'count' column:
0    500000
1     50000
Name: count, dtype: int64

Trying to access 'max' column with dot notation:
Type: <class 'method'>

Correct way to access 'max' column:
0    1000000
1     100000
Name: max, dtype: int64

Error 4: Assignment confusion

import pandas as pd

df = pd.DataFrame({'value': [10, 20, 30]})

df.new_column_dot = [100, 200, 300]

df['new_column_bracket'] = [100, 200, 300]

print("DataFrame columns:")
print(df.columns.tolist())

print("\nDataFrame contents:")
print(df)

print("\nChecking if 'new_column_dot' is in DataFrame:")
print('new_column_dot' in df.columns)

print("\nIt became a DataFrame attribute instead:")
print(hasattr(df, 'new_column_dot'))

result:

DataFrame columns:
['value', 'new_column_bracket']

DataFrame contents:
   value  new_column_bracket
0     10                 100
1     20                 200
2     30                 300

Checking if 'new_column_dot' is in DataFrame:
False

It became a DataFrame attribute instead:
True

Critical insight: Dot notation assignment creates Python attributes, not DataFrame columns. Always use square brackets to create new columns.

Comparison Table

Feature Dot Notation Square Bracket
Syntax df.column df['column']
With spaces ❌ Not allowed ✅ Works
Starts with number ❌ Not allowed ✅ Works
Special characters ❌ Not allowed ✅ Works
Variables ❌ Not supported ✅ Supported
Method conflicts ⚠️ Conflicts (count, sum, etc.) ✅ No conflicts
Column creation ⚠️ Creates attributes ✅ Creates columns
Autocomplete ✅ IDE support ⚠️ Limited
Readability ✅ Cleaner ⚠️ More verbose
Dictionaries ❌ Not supported ✅ Required

Best Practices

Use square brackets in production code for reliability

Use dot notation only for quick interactive analysis with simple column names

Always use brackets when column names might conflict with pandas methods

Always use brackets for column creation: df['new_col'] = ...

Use brackets when column names might change or come from external sources

Don't use dot notation for columns named after pandas methods

Don't mix both styles inconsistently in the same codebase

Avoid dot notation if column names aren't under your control

Common Use Cases

Data Analysis (dot notation - use with caution):

df.revenue.sum()  # Only if 'revenue' won't conflict
df.price.mean()
df.quantity.describe()

Production Code (square brackets - always safe):

df['Revenue (USD)'].sum()
df['2024 Price'].mean()
df['Order Count'].max()  # 'count' would conflict with df.count()

Dynamic Access (must use brackets):

metrics = ['revenue', 'profit', 'growth']
for metric in metrics:
    print(df[metric].describe())

Column Creation (always use brackets):

df['total'] = df['price'] * df['quantity']
df['margin'] = (df['profit'] / df['revenue']) * 100

Resources