Python映射对象不可下标


81

为什么以下脚本会给出错误:

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]

5
您在使用Python 3吗?
Felix Kling

@ user567797-这对我来说很好// @ Felix:他不使用python 3,因为他使用print作为语句!
Pushpak Dagade 2011年

2
在while循环之下的整个过程可以简化为payIntList = [int(x) + 1000 for x in payList]; print(*payIntList, sep='\n')(或for x in payIntList: print x在Python 2.x中print不是函数),而不会损失可读性(可以说,它甚至更具可读性)。

2
@Guanidene:他正在使用Python 3,因为他有地图对象。但是他正在尝试在上面运行Python 2代码,因此出现了错误。
Lennart Regebro

3
我想要一个“为什么在Python 3上运行Python 2代码时为什么会出错”的问题,我们可以将所有这些都标记为重复。;)
Lennart Regebro

Answers:


136

在Python 3中,map返回类型为的可迭代对象map,而不是可下标的列表,该列表允许您编写map[i]。要强制列出结果,请写

payIntList = list(map(int,payList))

但是,在许多情况下,您可以不使用索引来更好地编写代码。例如,使用列表推导

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

6
这个答案是正确的,但理想情况下,您不会将映射转换为此类用例的列表。地图已经可以迭代,并且与列表相比,迭代速度要快一个数量级。因此,您不仅不需要索引,也根本不需要列表。更清晰的代码是,因为payIntList已经是一张地图,for i in payIntList: print(i + 1000)
RustyToms '18

17

map()不返回列表,而是返回一个map对象。

list(map)如果您希望再次将其作为列表,则需要致电。

更好的是

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

不会占用创建中间对象的大量内存,它只会在ints创建它们时传递出去。

另外,您可以if choice.lower() == 'n':这样做,不必重复两次。

Python支持+=:你可以做payIntList[i] += 1000numElements += 1,如果你想要的。

如果您真的想变得棘手:

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

和/或

for payInt in payIntList:
    payInt += 1000
    print payInt

同样,四个空格是Python中的标准缩进量。


1
嗯,python3就是这种情况,但是在这里他似乎正在使用python2.x,因为他正在使用print作为语句。
Pushpak Dagade 2011年

您的代码段确实将所有int存储在列表中的内存中。使用迭代器确实非常有用,并且可以节省内存,尤其是在多层转换时,但是list在迭代器周围添加可以消除这种优势!

1
执行list(map(...))此操作时,将创建一个map,然后创建一个list,然后将其删除map,因此有一段时间会同时将它们都存储在内存中。当您这样做时list(imap(...)),情况并非如此。这就是为什么我说“用一个中间对象占用内存”
2011年

所以您假设使用Python 2?然后list(map(...))是多余的,因为-如文档所述,“的结果map始终是列表”。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.