Reversing a tuple and reversing a list returns objects of different type:
>>> reversed((1,2))
<reversed at 0x7fffe802f748>
>>> reversed([1,2])
<list_reverseiterator at 0x7fffebdd4400>
They have the same dir
. Neither type is a subclass of the other.
Why is that? What can one do that the other can't?
Since tuples are immutable, there is no way to reverse a tuple in-place.
reverse() actually reverses the elements in the container. reversed() doesn't actually reverse anything, it merely returns an object that can be used to iterate over the container's elements in reverse order. If that's what you need, it's often faster than actually reversing the elements.
In Python, you can reverse the items of lists ( list ) with using reverse() , reversed() , and slicing. If you want to reverse strings ( str ) and tuples ( tuple ), use reversed() or slice.
Python reversed() The reversed() method computes the reverse of a given sequence object and returns it in the form of a list.
Basically, a list implements the __reversed__
method and returns an specialized object, while tuple
falls back to the default implementation of reversed
for any sequence:
>>> list.__reversed__
<method '__reversed__' of 'list' objects>
>>> tuple.__reversed__
AttributeError: type object 'tuple' has no attribute '__reversed__'
Now, why list does not default to the sequence reversed
object has to be found in the source code for the list object itself - probably it enables some optimizations by accessing directly some of internal list
attributes.
Actually looking at the C code, there is little difference, and certainly nothing that catches the eye -
I'd dare say the special list __reversed__
implementation is a leftover from Python2 days where reversed
would actually copy any other Python sequence to a list
- so there would be no sense for other sequences to have special cases for it (and when they did implement the general enumreverse
it was just good enough for tuples).
I am pretty sure that if one would simply comment out the __reversed__
slot on listobject.c
, Python and its lists would work as if nothing had happened, defaulting to the general case reversed
.
According to Python's documentation:
object.__reversed__(self)
Called (if present) by the
reversed()
built-in to implement reverse iteration. It should return a new iterator object that iterates over all the objects in the container in reverse order.If the
__reversed__()
method is not provided, thereversed()
built-in will fall back to using the sequence protocol (__len__()
and__getitem__()
). Objects that support the sequence protocol should only provide__reversed__()
if they can provide an implementation that is more efficient than the one provided byreversed()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With