2

I'm writing a program that keeps asking the user to enter names until the word END is entered, at which point it prints out the list of names in reverse order.

At first, I didn't know how to print out a list in reverse order, so I found this: Traverse a list in reverse order in Python

I decided to use the reversed() built-in function:

import getpass
import time
import sys
print("Welcome " + getpass.getuser() + "...")
time.sleep(0.25)
print("This program, powered by Python, it will ask you to enter names...")
time.sleep(0.5)
print("...once you have finished, enter END to print off your list")
names = []
while True:
    name = input("Please enter a name: ")
    if name == "END":
        print(reversed(names))
        sys.exit()
    names.append(name)

However, all it prints is:

<list_reverseiterator object at 0x0000000002A14F28>

Why is this happening and how can I tackle this issue?

Many thanks

2
  • 9
    try print(list( reversed(names)) ) Commented Dec 24, 2013 at 13:11
  • All of these answers are good - I upvoted each of them, but the most detailed one is poke's. Commented Dec 24, 2013 at 13:21

6 Answers 6

5

reversed returns an iterator that will iterate the list in a reversed order. It will not return a reversed list. This is an important difference because if it returned a reversed list, then that list would have to be allocated in memory. So you would end up with a copy of it; and you would have to iterate over it twice (once for creating the reversed list, and then once for printing it).

Instead reversed just begins iterating at the end of the original list. You can easily see this if you modify the list after creating the reversed iterator:

>>> a = [1,2,3,4,5]
>>> r = reversed(a)
>>> a[2:2] = [10, 11, 12, 13]
>>> a
[1, 2, 10, 11, 12, 13, 3, 4, 5]
>>> list(r)
[12, 11, 10, 2, 1]

The reversed iterator just remembered the index where it would start iterating (i.e. index 4). With the modified list, this no longer is the end of the list though.

So, if you want to have a copied list in reversed order, you will have to call list on it, to create one from it. Otherwise, if you can, you should really just try to iterate on the reversed iterator.

Sign up to request clarification or add additional context in comments.

1 Comment

I prefer your answer on mine.
1

For the sake of efficiency, reversed returns an iterator object instead of a full list. This way, it doesn't have to allocate any additional space, or do much work at all, until the user starts iterating through it.

As pointed out by behzad, the easiest way to get your results in list form is to use list.

>>> seq = [1,2,3]
>>> x = reversed(seq)
>>> print list(x)
[3, 2, 1]

1 Comment

All of these answers are good - I upvoted each of them, but the most detailed one is poke's.
1

The reversed method does not return a list. Instead this returns an iterator. Iterators are objects that allows you to iterate over lists, dicts and any object that is iterable. Thus you need either to use it with a loop or convert it to list as @behzad.nouri suggested:

for item in reversed(names):
    print item

2 Comments

All of these answers are good - I upvoted each of them, but the most detailed one is poke's.
Yes, exactly! I have commented his answer to express the same intention of yours.
1

From http://docs.python.org/release/2.4.3/whatsnew/node7.html

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

use print list(reversed(names)) at the your method to print the list.

Fixed Code:

import getpass
import time
import sys
print("Welcome " + getpass.getuser() + "...")
time.sleep(0.25)
print("This program, powered by Python, it will ask you to enter names...")
time.sleep(0.5)
print("...once you have finished, enter END to print off your list")
names = []
while True:
    name = input("Please enter a name: ")
    if name == "END":
        print list((reversed(names)))
        sys.exit()
    names.append(name)

Output Example:

['fxvb', 'asd', 'asd']

1 Comment

All of these answers are good - I upvoted each of them, but the most detailed one is poke's.
1

reversed(seq) is a built-in function. Takes a sequence and returns an iterator that loops over the elements of the sequence in reverse order.

>>> x = [1, 2, 3, 4, 5]
>>> for a in reversed(x):
...     print a
... 
5
4
3
2
1

Comments

1

I would suggest using slicing - it's much more efficient

print(names[::-1]

For a list of 30 strings it is about 3 times faster

In [99]: %timeit names[::-1]
1000000 loops, best of 3: 264 ns per loop
In [103]: %timeit list(reversed(names))
1000000 loops, best of 3: 839 ns per loop

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.