Difference between [] and [[]] in Python
Categories:
Understanding Python's Indexing: The Difference Between [] and [[]]
![Hero image for Difference between [] and [[]] in Python](/img/5e47a400-hero.webp)
Explore the fundamental differences between single and double square brackets in Python, particularly in the context of list indexing, string slicing, and Pandas DataFrame operations.
In Python, square brackets []
are ubiquitous, serving various purposes from defining lists to accessing elements. However, the subtle distinction between []
(single brackets) and [[]]
(double brackets) can be a source of confusion, especially for newcomers. This article will demystify these two syntaxes, explaining their roles in basic Python data structures and, more importantly, in the powerful Pandas library.
Single Brackets []
: Accessing Elements and Slicing
Single square brackets are primarily used for indexing and slicing sequences (like lists, tuples, and strings) and for accessing items in mappings (like dictionaries). When used for indexing, they return a single element. When used for slicing, they return a new sequence (or sub-sequence) of the same type.
# List indexing
my_list = [10, 20, 30, 40, 50]
print(my_list[0]) # Output: 10
# List slicing
print(my_list[1:4]) # Output: [20, 30, 40]
# String indexing
my_string = "Python"
print(my_string[0]) # Output: P
# String slicing
print(my_string[1:3]) # Output: yt
# Dictionary item access
my_dict = {'a': 1, 'b': 2}
print(my_dict['a']) # Output: 1
Examples of single bracket usage for indexing and slicing in Python.
Double Brackets [[]]
: Lists of Indices/Columns and DataFrame Selection
Double square brackets [[]]
are not a distinct operator in Python's core language. Instead, they represent a single bracket operation where the argument passed inside is itself a list. This pattern becomes particularly significant and common when working with libraries like Pandas, where it's used for selecting multiple columns or rows, often returning a DataFrame even if only one column is selected.
flowchart TD A["Python Object"] --> B{"Is it a Pandas DataFrame?"} B -- Yes --> C{"`df[[]]` (list of columns)"} C --> D["Returns a DataFrame (even for single column)"] B -- No --> E{"`obj[[]]` (list as index)"} E --> F["Returns element at index 0 of the list, then uses that as index for obj"] F --> G["Error if list is not a valid index or if obj is not indexable by a list"] D --> H[End] G --> H[End]
Decision flow for interpreting [[]]
in Python.
[[]]
as obj[[item1, item2, ...]]
. The inner []
creates a list, and the outer []
uses that list for indexing or selection.The Pandas Perspective: []
vs. [[]]
in DataFrames
The distinction between []
and [[]]
is most pronounced and critical when working with Pandas DataFrames. Understanding this difference is key to correctly selecting data and maintaining desired data structures.
Single Brackets df[]
in Pandas
When used with a Pandas DataFrame, df[]
can perform several actions depending on the type of argument passed:
- Column Selection (single column): If you pass a single column name (as a string), it selects that column and returns a Pandas Series.
- Row Slicing: If you pass a slice object (e.g.,
df[0:3]
), it selects rows by integer position. - Boolean Indexing: If you pass a boolean Series or array, it filters rows based on the
True
values. - Column Selection (list of columns - special case): If you pass a list of column names, it selects those columns and returns a DataFrame. This is where
[[]]
comes into play.
import pandas as pd
data = {'colA': [1, 2, 3], 'colB': [4, 5, 6], 'colC': [7, 8, 9]}
df = pd.DataFrame(data)
print("Original DataFrame:\n", df)
# 1. Single column selection (returns Series)
series_col_a = df['colA']
print("\nSeries from df['colA']:\n", series_col_a)
print("Type:", type(series_col_a))
# 2. Row slicing
rows_slice = df[0:2]
print("\nRows slice df[0:2]:\n", rows_slice)
# 3. Boolean indexing
filtered_df = df[df['colA'] > 1]
print("\nFiltered DataFrame (df['colA'] > 1):\n", filtered_df)
Examples of single bracket usage in Pandas DataFrames.
Double Brackets df[[]]
in Pandas
When you use df[[]]
in Pandas, you are essentially passing a list of column names to the DataFrame's indexing operator. This syntax is specifically designed for selecting one or more columns while always returning a DataFrame, even if you select only a single column. This behavior is crucial for maintaining consistency in your data structures.
import pandas as pd
data = {'colA': [1, 2, 3], 'colB': [4, 5, 6], 'colC': [7, 8, 9]}
df = pd.DataFrame(data)
# Selecting a single column using double brackets (returns DataFrame)
df_col_a = df[['colA']]
print("DataFrame from df[['colA']]:\n", df_col_a)
print("Type:", type(df_col_a))
# Selecting multiple columns using double brackets (returns DataFrame)
df_cols_ab = df[['colA', 'colB']]
print("\nDataFrame from df[['colA', 'colB']]:\n", df_cols_ab)
print("Type:", type(df_cols_ab))
Examples of double bracket usage in Pandas DataFrames.
df['col_name']
returns a Series, while df[['col_name']]
returns a DataFrame. This distinction is vital for subsequent operations that expect a DataFrame.