Garrett
Garrett

Reputation: 4404

Why does Python have `reversed`?

Why does Python have the built-in function reversed?

Why not just use x[::-1] instead of reversed(x)?


Edit: @TanveerAlam pointed out that reversed is not actually a function, but rather a class, despite being listed on the page Built-in Functions.

Upvotes: 4

Views: 424

Answers (6)

Tanveer Alam
Tanveer Alam

Reputation: 5275

First of all, reversed is not a built-in function.

>>> type(reversed)
<type 'type'>

It's a class which itrates over a sequence and gives a reverse order of sequence.

Try:

>>> help(reversed)
Help on class reversed in module __builtin__:

class reversed(object)
 |  reversed(sequence) -> reverse iterator over values of the sequence

And when we pass a parameter to it, it acts as a iterator,

>>> l = [1, 2, 3, 4]
>>> obj = reversed(l)
>>> obj
<listreverseiterator object at 0x0220F950>
>>> obj.next()
4
>>> obj.next()
3
>>> obj.next()
2
>>> obj.next()
1
>>> obj.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

whereas a slice operation returns the whole list which is not memory efficient for larger lists.

That is why, in Python 2, we have range (which returns whole list) as well as xrange (which generates each element on every iteration).

>>> l[::-1]
[4, 3, 2, 1]

Upvotes: 1

John La Rooy
John La Rooy

Reputation: 304393

reversed returns a reverse iterator.

[::-1] asks the object for a slice

Python objects try to return what you probably expect

>>> [1, 2, 3][::-1]
[3, 2, 1]
>>> "123"[::-1]
'321'

This is convenient - particularly for strings and tuples.

But remember the majority of code doesn't need to reverse strings.

The most important role of reversed() is making code easier to read and understand.

The fact that it returns an iterator without creating a new sequence is of secondary importance

From the docs

PEP 322: Reverse Iteration A new built-in function, reversed(seq)(), takes a sequence and returns an iterator that loops over the elements of the sequence in reverse order.

>>>
>>> for i in reversed(xrange(1,4)):
...    print i
...
3
2
1

Compared to extended slicing, such as range(1,4)[::-1], reversed() is easier to read, runs faster, and uses substantially less memory.

Note that reversed() only accepts sequences, not arbitrary iterators. If you want to reverse an iterator, first convert it to a list with list().

>>>
>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
...   print line
...

Upvotes: 3

Sunisdown
Sunisdown

Reputation: 9

reversed return a reverse iterator.

x[::-1] return a list.

In [1]: aaa = [1,2,3,4,5]

In [4]: aaa[::-1]
Out[4]: [5, 4, 3, 2, 1]

In [5]: timeit(aaa[::-1])
1000000 loops, best of 3: 206 ns per loop

In [6]: reversed(aaa)
Out[6]: <listreverseiterator at 0x104310d50>

In [7]: timeit(reversed(aaa))
10000000 loops, best of 3: 182 ns per loop

Upvotes: 1

Andy
Andy

Reputation: 50610

aList = [123, 'xyz', 'zara', 'abc', 'xyz'];
print type(reversed(aList))

bList = [123, 'xyz', 'zara', 'abc', 'xyz'];
print type(bList[::-1])

Output:

<type 'listreverseiterator'>
<type 'list'>

The reversed function returns a reverse iterator. The [::-1] returns a list.

Upvotes: 0

oopcode
oopcode

Reputation: 1962

Because reversed returns an iterator.

Upvotes: -1

Enrico Granata
Enrico Granata

Reputation: 3329

>>> a= [1,2,3,4,5,6,7,8,9,10]
>>> a[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> reversed(a)
<listreverseiterator object at 0x10dbf5390>

The first notation is generating the reverse eagerly; the second is giving you a reverse iterator, which is possibly cheaper to acquire, as it has potential to only generate elements as needed

Upvotes: 8

Related Questions