90
votes

Why does the following script give the error:

payIntList[i] = payIntList[i] + 1000
TypeError: 'map' object is not subscriptable

payList = []
numElements = 0

while True:
        payValue = raw_input("Enter the pay amount: ")
        numElements = numElements + 1
        payList.append(payValue)
        choice = raw_input("Do you wish to continue(y/n)?")
        if choice == 'n' or choice == 'N':
                         break

payIntList = map(int,payList)

for i in range(numElements):
         payIntList[i] = payIntList[i] + 1000
         print payIntList[i]
2
Are you using Python 3 ? - Felix Kling
@user567797 - This works fine for me @ Felix: He is not using python 3 as he is using print as a statement! - Pushpak Dagade
The whole thing below the while loop can be shortened to payIntList = [int(x) + 1000 for x in payList]; print(*payIntList, sep='\n') (or for x in payIntList: print x in Python 2.x where print isn't a function) without losing readability (arguably, it's even more readable). - user395760
@Guanidene: He is using Python 3, as he has map objects. But he is trying to run Python 2 code on it, hence the errors. - Lennart Regebro
I'd like a "Why do I get errors when I run Python 2 code on Python 3" question, that we can mark all of these as duplicates to. ;) - Lennart Regebro

2 Answers

153
votes

In Python 3, map returns an iterable object of type map, and not a subscriptible list, which would allow you to write map[i]. To force a list result, write

payIntList = list(map(int,payList))

However, in many cases, you can write out your code way nicer by not using indices. For example, with list comprehensions:

payIntList = [pi + 1000 for pi in payList]
for pi in payIntList:
    print(pi)
19
votes

map() doesn't return a list, it returns a map object.

You need to call list(map) if you want it to be a list again.

Even better,

from itertools import imap
payIntList = list(imap(int, payList))

Won't take up a bunch of memory creating an intermediate object, it will just pass the ints out as it creates them.

Also, you can do if choice.lower() == 'n': so you don't have to do it twice.

Python supports +=: you can do payIntList[i] += 1000 and numElements += 1 if you want.

If you really want to be tricky:

from itertools import count
for numElements in count(1):
    payList.append(raw_input("Enter the pay amount: "))
    if raw_input("Do you wish to continue(y/n)?").lower() == 'n':
         break

and / or

for payInt in payIntList:
    payInt += 1000
    print payInt

Also, four spaces is the standard indent amount in Python.