@@ -113,10 +113,26 @@ def __init__(self, left, right=None, op=None):
113
113
Do not use this directly, use `cycler` function instead.
114
114
"""
115
115
self ._keys = _process_keys (left , right )
116
- self ._left = copy .deepcopy (left )
117
- self ._right = copy .deepcopy (right )
116
+ if isinstance (left , Cycler ):
117
+ self ._left = left ._shallow_copy ()
118
+ else :
119
+ self ._left = copy .copy (left )
120
+
121
+ if isinstance (right , Cycler ):
122
+ self ._right = right ._shallow_copy ()
123
+ else :
124
+ self ._right = copy .copy (right )
125
+
118
126
self ._op = op
119
127
128
+ def _shallow_copy (self ):
129
+ ret = Cycler (None )
130
+ ret ._keys = self .keys
131
+ ret ._left = copy .copy (self ._left )
132
+ ret ._right = copy .copy (self ._right )
133
+ ret ._op = copy .copy (self ._op )
134
+ return ret
135
+
120
136
@property
121
137
def keys (self ):
122
138
"""
@@ -228,11 +244,14 @@ def __iadd__(self, other):
228
244
other : Cycler
229
245
The second Cycler
230
246
"""
231
- old_self = copy .deepcopy (self )
247
+ if not isinstance (other , Cycler ):
248
+ raise TypeError ("Cannot += with a non-Cycler object" )
249
+ # True shallow copy of self is fine since this is in-place
250
+ old_self = copy .copy (self )
232
251
self ._keys = _process_keys (old_self , other )
233
252
self ._left = old_self
234
253
self ._op = zip
235
- self ._right = copy . deepcopy ( other )
254
+ self ._right = other . _shallow_copy ( )
236
255
return self
237
256
238
257
def __imul__ (self , other ):
@@ -244,12 +263,14 @@ def __imul__(self, other):
244
263
other : Cycler
245
264
The second Cycler
246
265
"""
247
-
248
- old_self = copy .deepcopy (self )
266
+ if not isinstance (other , Cycler ):
267
+ raise TypeError ("Cannot *= with a non-Cycler object" )
268
+ # True shallow copy of self is fine since this is in-place
269
+ old_self = copy .copy (self )
249
270
self ._keys = _process_keys (old_self , other )
250
271
self ._left = old_self
251
272
self ._op = product
252
- self ._right = copy . deepcopy ( other )
273
+ self ._right = other . _shallow_copy ( )
253
274
return self
254
275
255
276
def __eq__ (self , other ):
@@ -354,7 +375,7 @@ def cycler(*args, **kwargs):
354
375
Parameters
355
376
----------
356
377
arg : Cycler
357
- Copy constructor for Cycler.
378
+ Copy constructor for Cycler (does a shallow copy of iterables) .
358
379
359
380
label : name
360
381
The property key. In the 2-arg form of the function,
@@ -363,6 +384,8 @@ def cycler(*args, **kwargs):
363
384
364
385
itr : iterable
365
386
Finite length iterable of the property values.
387
+ Can be a single-property `Cycler` that would
388
+ be like a key change, but as a shallow copy.
366
389
367
390
Returns
368
391
-------
@@ -378,7 +401,7 @@ def cycler(*args, **kwargs):
378
401
if not isinstance (args [0 ], Cycler ):
379
402
raise TypeError ("If only one positional argument given, it must "
380
403
" be a Cycler instance." )
381
- return copy . deepcopy (args [0 ])
404
+ return Cycler (args [0 ])
382
405
elif len (args ) == 2 :
383
406
return _cycler (* args )
384
407
elif len (args ) > 2 :
@@ -415,10 +438,9 @@ def _cycler(label, itr):
415
438
msg = "Can not create Cycler from a multi-property Cycler"
416
439
raise ValueError (msg )
417
440
418
- if label in keys :
419
- return copy .deepcopy (itr )
420
- else :
421
- lab = keys .pop ()
422
- itr = list (v [lab ] for v in itr )
441
+ lab = keys .pop ()
442
+ # Doesn't need to be a new list because
443
+ # _from_iter() will be creating that new list anyway.
444
+ itr = (v [lab ] for v in itr )
423
445
424
446
return Cycler ._from_iter (label , itr )
0 commit comments