Skip to content

Commit 64b381d

Browse files
committed
Address comments.
1. Ensure we return named tuples in more cases (when using python >= 3.7) 2. Move test around to be with the itertuples test 3. Update docstring with the new behaviour.
1 parent e4b035e commit 64b381d

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

pandas/core/frame.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
from pandas._libs import algos as libalgos, lib
4040
from pandas._typing import Axes, Dtype, FilePathOrBuffer
41+
from pandas.compat import PY37
4142
from pandas.compat._optional import import_optional_dependency
4243
from pandas.compat.numpy import function as nv
4344
from pandas.util._decorators import (
@@ -975,7 +976,8 @@ def itertuples(self, index=True, name="Pandas"):
975976
-----
976977
The column names will be renamed to positional names if they are
977978
invalid Python identifiers, repeated, or start with an underscore.
978-
With a large number of columns (>255), regular tuples are returned.
979+
On python versions < 3.7 regular tuples are returned for DataFrames
980+
with a large number of columns (>254).
979981
980982
Examples
981983
--------
@@ -1018,8 +1020,9 @@ def itertuples(self, index=True, name="Pandas"):
10181020
# use integer indexing because of possible duplicate column names
10191021
arrays.extend(self.iloc[:, k] for k in range(len(self.columns)))
10201022

1021-
# Python versions before 3.7 support at most 255 arguments to constructor
1022-
if name is not None and len(self.columns) + index < 255:
1023+
# Python versions before 3.7 support at most 255 arguments to constructors
1024+
can_return_named_tuples = PY37 or len(self.columns) + index < 255
1025+
if name is not None and can_return_named_tuples:
10231026
itertuple = collections.namedtuple(name, fields, rename=True)
10241027
return map(itertuple._make, zip(*arrays))
10251028

pandas/tests/frame/test_api.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import numpy as np
66
import pytest
77

8+
from pandas.compat import PY37
9+
810
import pandas as pd
911
from pandas import Categorical, DataFrame, Series, compat, date_range, timedelta_range
1012
import pandas.util.testing as tm
@@ -261,8 +263,27 @@ def test_itertuples(self, float_frame):
261263
df3 = DataFrame({"f" + str(i): [i] for i in range(1024)})
262264
# will raise SyntaxError if trying to create namedtuple
263265
tup3 = next(df3.itertuples())
264-
assert not hasattr(tup3, "_fields")
265266
assert isinstance(tup3, tuple)
267+
if PY37:
268+
assert hasattr(tup3, "_fields")
269+
else:
270+
assert not hasattr(tup3, "_fields")
271+
272+
# GH 28282
273+
df_254_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(254)}])
274+
result_254_columns = next(df_254_columns.itertuples(index=False))
275+
assert isinstance(result_254_columns, tuple)
276+
assert hasattr(result_254_columns, "_fields")
277+
278+
df_255_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(255)}])
279+
result_255_columns = next(df_255_columns.itertuples(index=False))
280+
assert isinstance(result_255_columns, tuple)
281+
282+
# Dataframes with >=255 columns will fallback to regular tuples on python < 3.7
283+
if PY37:
284+
assert hasattr(result_255_columns, "_fields")
285+
else:
286+
assert not hasattr(result_255_columns, "_fields")
266287

267288
def test_sequence_like_with_categorical(self):
268289

@@ -288,22 +309,6 @@ def test_sequence_like_with_categorical(self):
288309
for c, col in df.items():
289310
str(s)
290311

291-
def test_itertuples_fallback_to_regular_tuples(self):
292-
# GH 28282
293-
294-
df_254_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(254)}])
295-
result_254_columns = next(df_254_columns.itertuples(index=False))
296-
assert isinstance(result_254_columns, tuple)
297-
assert result_254_columns.foo_1 == "bar_1"
298-
299-
df_255_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(255)}])
300-
result_255_columns = next(df_255_columns.itertuples(index=False))
301-
assert isinstance(result_255_columns, tuple)
302-
303-
# Dataframes with >=255 columns will fallback to regular tuples
304-
with pytest.raises(AttributeError):
305-
result_255_columns.foo_1
306-
307312
def test_len(self, float_frame):
308313
assert len(float_frame) == len(float_frame.index)
309314

0 commit comments

Comments
 (0)