Skip to content

Commit 9313089

Browse files
toobazjreback
authored andcommitted
BUG: Make dict iterators real iterators, provide "next()" in Python 2
Author: Pietro Battiston <[email protected]> Closes #12299 from toobaz/compat_iters and squashes the following commits: 1d18284 [Pietro Battiston] BUG: Panels don't behave as dicts (.e.g ".items" is not callable) 2d03e4f [Pietro Battiston] BUG: Make dict iterators real iterators, provide "next()" in Python 2
1 parent 9b9c7a7 commit 9313089

File tree

13 files changed

+43
-41
lines changed

13 files changed

+43
-41
lines changed

doc/source/whatsnew/v0.18.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ Bug Fixes
11281128
- Work around compat issues with ``boto`` in python 3.5 (:issue:`11915`)
11291129
- Bug in ``NaT`` subtraction from ``Timestamp`` or ``DatetimeIndex`` with timezones (:issue:`11718`)
11301130
- Bug in subtraction of ``Series`` of a single tz-aware ``Timestamp`` (:issue:`12290`)
1131-
1131+
- Use compat iterators in PY2 to support ``.next()`` (:issue:`12299`)
11321132
- Bug in ``Timedelta.round`` with negative values (:issue:`11690`)
11331133
- Bug in ``.loc`` against ``CategoricalIndex`` may result in normal ``Index`` (:issue:`11586`)
11341134
- Bug in ``DataFrame.info`` when duplicated column names exist (:issue:`11761`)

pandas/compat/__init__.py

+16-19
Original file line numberDiff line numberDiff line change
@@ -153,31 +153,28 @@ def signature(f):
153153
lfilter = builtins.filter
154154

155155

156-
def iteritems(obj, **kwargs):
157-
"""replacement for six's iteritems for Python2/3 compat
158-
uses 'iteritems' if available and otherwise uses 'items'.
156+
if PY2:
157+
def iteritems(obj, **kw):
158+
return obj.iteritems(**kw)
159159

160-
Passes kwargs to method.
161-
"""
162-
func = getattr(obj, "iteritems", None)
163-
if not func:
164-
func = obj.items
165-
return func(**kwargs)
160+
def iterkeys(obj, **kw):
161+
return obj.iterkeys(**kw)
166162

163+
def itervalues(obj, **kw):
164+
return obj.itervalues(**kw)
167165

168-
def iterkeys(obj, **kwargs):
169-
func = getattr(obj, "iterkeys", None)
170-
if not func:
171-
func = obj.keys
172-
return func(**kwargs)
166+
next = lambda it : it.next()
167+
else:
168+
def iteritems(obj, **kw):
169+
return iter(obj.items(**kw))
173170

171+
def iterkeys(obj, **kw):
172+
return iter(obj.keys(**kw))
174173

175-
def itervalues(obj, **kwargs):
176-
func = getattr(obj, "itervalues", None)
177-
if not func:
178-
func = obj.values
179-
return func(**kwargs)
174+
def itervalues(obj, **kw):
175+
return iter(obj.values(**kw))
180176

177+
next = next
181178

182179
def bind_method(cls, name, func):
183180
"""Bind a method to class, python 2 and python 3 compatible.

pandas/core/generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3119,7 +3119,7 @@ def fillna(self, value=None, method=None, axis=None, inplace=False,
31193119

31203120
# fill in 2d chunks
31213121
result = dict([(col, s.fillna(method=method, value=value))
3122-
for col, s in compat.iteritems(self)])
3122+
for col, s in self.iteritems()])
31233123
return self._constructor.from_dict(result).__finalize__(self)
31243124

31253125
# 2d or less

pandas/core/panel.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ def to_sparse(self, fill_value=None, kind='block'):
398398
y : SparseDataFrame
399399
"""
400400
from pandas.core.sparse import SparsePanel
401-
frames = dict(compat.iteritems(self))
401+
frames = dict(self.iteritems())
402402
return SparsePanel(frames, items=self.items,
403403
major_axis=self.major_axis,
404404
minor_axis=self.minor_axis, default_kind=kind,
@@ -450,7 +450,7 @@ def to_excel(self, path, na_rep='', engine=None, **kwargs):
450450
writer = path
451451
kwargs['na_rep'] = na_rep
452452

453-
for item, df in compat.iteritems(self):
453+
for item, df in self.iteritems():
454454
name = str(item)
455455
df.to_excel(writer, name, **kwargs)
456456
writer.save()

pandas/io/pytables.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2726,7 +2726,7 @@ def write(self, obj, **kwargs):
27262726
self.attrs.default_kind = obj.default_kind
27272727
self.write_index('items', obj.items)
27282728

2729-
for name, sdf in compat.iteritems(obj):
2729+
for name, sdf in obj.iteritems():
27302730
key = 'sparse_frame_%s' % name
27312731
if key not in self.group._v_children:
27322732
node = self._handle.create_group(self.group, key)

pandas/sparse/panel.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def _combine(self, other, func, axis=0):
393393
return self._combinePanel(other, func)
394394
elif lib.isscalar(other):
395395
new_frames = dict((k, func(v, other))
396-
for k, v in compat.iteritems(self))
396+
for k, v in self.iteritems())
397397
return self._new_like(new_frames)
398398

399399
def _combineFrame(self, other, func, axis=0):
@@ -470,7 +470,7 @@ def major_xs(self, key):
470470
y : DataFrame
471471
index -> minor axis, columns -> items
472472
"""
473-
slices = dict((k, v.xs(key)) for k, v in compat.iteritems(self))
473+
slices = dict((k, v.xs(key)) for k, v in self.iteritems())
474474
return DataFrame(slices, index=self.minor_axis, columns=self.items)
475475

476476
def minor_xs(self, key):
@@ -487,7 +487,7 @@ def minor_xs(self, key):
487487
y : SparseDataFrame
488488
index -> major axis, columns -> items
489489
"""
490-
slices = dict((k, v[key]) for k, v in compat.iteritems(self))
490+
slices = dict((k, v[key]) for k, v in self.iteritems())
491491
return SparseDataFrame(slices, index=self.major_axis,
492492
columns=self.items,
493493
default_fill_value=self.default_fill_value,

pandas/sparse/tests/test_sparse.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def assert_sp_frame_equal(left, right, exact_indices=True):
104104

105105

106106
def assert_sp_panel_equal(left, right, exact_indices=True):
107-
for item, frame in compat.iteritems(left):
107+
for item, frame in left.iteritems():
108108
assert (item in right)
109109
# trade-off?
110110
assert_sp_frame_equal(frame, right[item], exact_indices=exact_indices)

pandas/stats/tests/test_fama_macbeth.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def checkFamaMacBethExtended(self, window_type, x, y, **kwds):
4444
end = index[i + window - 1]
4545

4646
x2 = {}
47-
for k, v in compat.iteritems(x):
47+
for k, v in x.iteritems():
4848
x2[k] = v.truncate(start, end)
4949
y2 = y.truncate(start, end)
5050

pandas/stats/tests/test_ols.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ def test_wls_panel(self):
573573

574574
stack_y = y.stack()
575575
stack_x = DataFrame(dict((k, v.stack())
576-
for k, v in compat.iteritems(x)))
576+
for k, v in x.iteritems()))
577577

578578
weights = x.std('items')
579579
stack_weights = weights.stack()

pandas/tests/test_compat.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"""
55

66
from pandas.compat import (range, zip, map, filter, lrange, lzip, lmap,
7-
lfilter, builtins)
7+
lfilter, builtins, iterkeys, itervalues, iteritems,
8+
next)
89
import pandas.util.testing as tm
910

1011

@@ -61,3 +62,8 @@ def test_zip(self):
6162
expected = list(builtins.zip(*lst)),
6263
lengths = 10,
6364
self.check_result(actual, expected, lengths)
65+
66+
def test_dict_iterators(self):
67+
self.assertEqual(next(itervalues({1: 2})), 2)
68+
self.assertEqual(next(iterkeys({1: 2})), 1)
69+
self.assertEqual(next(iteritems({1: 2})), (1, 2))

pandas/tests/test_panel.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,10 @@ def test_keys(self):
318318
def test_iteritems(self):
319319
# Test panel.iteritems(), aka panel.iteritems()
320320
# just test that it works
321-
for k, v in compat.iteritems(self.panel):
321+
for k, v in self.panel.iteritems():
322322
pass
323323

324-
self.assertEqual(len(list(compat.iteritems(self.panel))),
324+
self.assertEqual(len(list(self.panel.iteritems())),
325325
len(self.panel.items))
326326

327327
@ignore_sparse_panel_future_warning
@@ -1105,7 +1105,7 @@ def test_ctor_dict(self):
11051105
assert_panel_equal(result, expected)
11061106

11071107
def test_constructor_dict_mixed(self):
1108-
data = dict((k, v.values) for k, v in compat.iteritems(self.panel))
1108+
data = dict((k, v.values) for k, v in self.panel.iteritems())
11091109
result = Panel(data)
11101110
exp_major = Index(np.arange(len(self.panel.major_axis)))
11111111
self.assertTrue(result.major_axis.equals(exp_major))
@@ -1872,7 +1872,7 @@ def test_shift(self):
18721872
# negative numbers, #2164
18731873
result = self.panel.shift(-1)
18741874
expected = Panel(dict((i, f.shift(-1)[:-1])
1875-
for i, f in compat.iteritems(self.panel)))
1875+
for i, f in self.panel.iteritems()))
18761876
assert_panel_equal(result, expected)
18771877

18781878
# mixed dtypes #6959
@@ -2072,7 +2072,7 @@ def test_to_excel(self):
20722072
except ImportError:
20732073
raise nose.SkipTest("need xlwt xlrd openpyxl")
20742074

2075-
for item, df in compat.iteritems(self.panel):
2075+
for item, df in self.panel.iteritems():
20762076
recdf = reader.parse(str(item), index_col=0)
20772077
assert_frame_equal(df, recdf)
20782078

@@ -2092,7 +2092,7 @@ def test_to_excel_xlsxwriter(self):
20922092
except ImportError as e:
20932093
raise nose.SkipTest("cannot write excel file: %s" % e)
20942094

2095-
for item, df in compat.iteritems(self.panel):
2095+
for item, df in self.panel.iteritems():
20962096
recdf = reader.parse(str(item), index_col=0)
20972097
assert_frame_equal(df, recdf)
20982098

pandas/tests/test_panel4d.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from pandas.core.panel4d import Panel4D
1313
from pandas.core.series import remove_na
1414
import pandas.core.common as com
15-
from pandas import compat
1615

1716
from pandas.util.testing import (assert_panel_equal,
1817
assert_panel4d_equal,
@@ -232,7 +231,7 @@ def test_keys(self):
232231
def test_iteritems(self):
233232
"""Test panel4d.iteritems()"""
234233

235-
self.assertEqual(len(list(compat.iteritems(self.panel4d))),
234+
self.assertEqual(len(list(self.panel4d.iteritems())),
236235
len(self.panel4d.labels))
237236

238237
def test_combinePanel4d(self):
@@ -731,7 +730,7 @@ def test_ctor_dict(self):
731730
# assert_panel_equal(result, expected)
732731

733732
def test_constructor_dict_mixed(self):
734-
data = dict((k, v.values) for k, v in compat.iteritems(self.panel4d))
733+
data = dict((k, v.values) for k, v in self.panel4d.iteritems())
735734
result = Panel4D(data)
736735
exp_major = Index(np.arange(len(self.panel4d.major_axis)))
737736
self.assertTrue(result.major_axis.equals(exp_major))

pandas/tools/tests/test_merge.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2671,7 +2671,7 @@ def test_panel_join_many(self):
26712671

26722672
data_dict = {}
26732673
for p in panels:
2674-
data_dict.update(compat.iteritems(p))
2674+
data_dict.update(p.iteritems())
26752675

26762676
joined = panels[0].join(panels[1:], how='inner')
26772677
expected = Panel.from_dict(data_dict, intersect=True)

0 commit comments

Comments
 (0)