Skip to content

Commit 6de8beb

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 6de8beb

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
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 & 18 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,26 @@ 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")
265-
assert isinstance(tup3, tuple)
266+
if PY37:
267+
assert hasattr(tup3, "_fields")
268+
else:
269+
assert not hasattr(tup3, "_fields")
270+
271+
# GH 28282
272+
df_254_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(254)}])
273+
result_254_columns = next(df_254_columns.itertuples(index=False))
274+
assert isinstance(result_254_columns, tuple)
275+
assert hasattr(result_254_columns, "_fields")
276+
277+
df_255_columns = DataFrame([{f"foo_{i}": f"bar_{i}" for i in range(255)}])
278+
result_255_columns = next(df_255_columns.itertuples(index=False))
279+
assert isinstance(result_255_columns, tuple)
280+
281+
# Dataframes with >=255 columns will fallback to regular tuples on python < 3.7
282+
if PY37:
283+
assert hasattr(result_255_columns, "_fields")
284+
else:
285+
assert not hasattr(result_255_columns, "_fields")
266286

267287
def test_sequence_like_with_categorical(self):
268288

@@ -288,22 +308,6 @@ def test_sequence_like_with_categorical(self):
288308
for c, col in df.items():
289309
str(s)
290310

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-
307311
def test_len(self, float_frame):
308312
assert len(float_frame) == len(float_frame.index)
309313

0 commit comments

Comments
 (0)