Open graingert opened 8 years ago
PyPy range objects internally behave like list-ishes
I suspect the trick is to try and pass-through index lookups when not passed a generator?
Yep python3 ranges are list-ish too. Lookups should be done that way you're right.
We are also working on sensible (i.e. space-efficient :) support for modifications to the listish
even if the underlying iterable is immutable
Additionally I think there's an open question on whether modifying listish
es if the underlying iterable is mutable. Maybe modifying the original iterable is less surprising, and if users don't want that they can always pass in a copy (difficult to go the other way around)
mutability wrapping could easily a whole new library, eg what if the items in the list are mutated?
interesting stuff in https://docs.python.org/2/library/itertools.html#itertools.tee
mutability wrapping is kind of half the point of listish (otherwise we'd just have made Tupleish
), but good point re. mutations in the input object.
As the tee
docs mention it's not safe to modify the source iterable after using tee on it. We have the same problem already with mutable inputs just when reading, as if the source is modified after we read past the index where the modification occurs we will be out of step.
i.e.
>>> l = [0, 1, 2, 3, 4, 5]
>>> listish = Listish(l)
>>> listish[3]
3
>>> l[1] = 'b'
>>> listish[1] != l[1]
True
>>> # and worse
>>> l.insert(3, 'd')
>>> list(iter(listish))
[0, 1, 2, 3, 3, 4, 5]
>>> l
[0, 'b', 2, 'd', 3, 4, 5]
We can't control what people might do to the list after passing it to Listish
, so I suppose it should just come with a warning like itertools.tee
does.
I think based on that it makes sense to ignore whether the input is mutable or not and treat it as if it isn't.
(perhaps we could add a flag to __new__
in case people want to be able to ignore whether the input is immutable? e.g.
>>> repr(Listish((,), passthrough_mutables=True))
Listish
>>> repr(Listish(someiter, passthrough_mutables=True))
Listish
>>> repr(Listish([1, 2, 3, 4], passthrough_mutables=True))
[1, 2, 3, 4]
>>> repr(Listish([1, 2, 3, 4]))
Listish
(obviously we could improve our reprs but that's a separate issue :) I don't know if there's any need for this though, thoughts?)
lists, tuples and listish already support indexing
range/xrange have varying magic behaviour depending on CPython 2, CPython 3 or PyPy