【问题标题】:Python map object is not subscriptablePython 地图对象不可下标
【发布时间】:2011-10-11 15:27:41
【问题描述】:

为什么下面的脚本会报错:

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]

【问题讨论】:

  • 你在使用 Python 3 吗?
  • @user567797 - 这对我来说很好@Felix:他没有使用 python 3,因为他使用 print 作为语句!
  • while 循环下方的整个内容可以缩短为 payIntList = [int(x) + 1000 for x in payList]; print(*payIntList, sep='\n')(或在 Python 2.x 中为 for x in payIntList: print x,其中 print 不是函数)而不会失去可读性(可以说,它甚至是更具可读性)。
  • @Guanidene:他使用的是 Python 3,因为他有地图对象。但他正试图在其上运行 Python 2 代码,因此出现了错误。
  • 我想要一个“为什么我在 Python 3 上运行 Python 2 代码时会出错”的问题,我们可以将所有这些标记为重复项。 ;)

标签: python python-3.x


【解决方案1】:

在pypy3或python3中不需要使用range来解决这个问题,所以实际上是少了代码..

for i in payIntList: print ( i + 1000 )

巧合的是,RustyTom 在上述 PhiHag 的解决方案中的评论相匹配。注意:不能在 pypy3 或 python3 中使用数组括号 [] 引用地图,否则会抛出相同的错误。

payIntList[i] 

Map ref 导致错误。

【讨论】:

    【解决方案2】:

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

    payIntList = list(map(int,payList))
    

    但是,在许多情况下,您可以通过不使用索引来更好地编写代码。比如list comprehensions:

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

    【讨论】:

    • 这个答案是正确的,但理想情况下,您不会将地图转换为此类用例的列表。地图已经是可迭代的,与列表相比,它的迭代速度似乎快了一个数量级。因此,您不仅不需要索引,而且根本不需要列表。更简洁的代码是,因为 payIntList 已经是一张地图,for i in payIntList: print(i + 1000)
    【解决方案3】:

    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 中的标准缩进量。

    【讨论】:

    • 好吧,python3就是这种情况,但在这里他似乎在使用python2.x,因为他使用print作为语句。
    • 您的代码 sn-p 确实将内存中的所有整数存储在一个列表中。使用迭代器确实很有用并且可以节省内存,尤其是在多层转换的情况下,但是在迭代器周围添加list 会失去这个优势!
    • 当您执行list(map(...)) 时,它会创建一个map,然后创建一个list,然后删除map,因此有一段时间两者都同时在内存中。当您执行list(imap(...)) 时,情况并非如此。这就是为什么我说“用 intermediate 对象占用内存”
    • 所以你假设 Python 2?那么list(map(...)) 是多余的,因为 - 正如documentation 所述,“[map] 的结果始终是一个列表”。
    猜你喜欢
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 2018-08-19
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多