【问题标题】:TypeError: 'filter' object is not subscriptableTypeError:“过滤器”对象不可下标
【发布时间】:2013-03-30 08:48:49
【问题描述】:

我收到错误消息

TypeError: 'filter' object is not subscriptable

当尝试运行以下代码块时

bonds_unique = {}
for bond in bonds_new:
    if bond[0] < 0:
        ghost_atom = -(bond[0]) - 1
        bond_index = 0
    elif bond[1] < 0:
        ghost_atom = -(bond[1]) - 1
        bond_index = 1
    else: 
        bonds_unique[repr(bond)] = bond
        continue
    if sheet[ghost_atom][1] > r_length or sheet[ghost_atom][1] < 0:
        ghost_x = sheet[ghost_atom][0]
        ghost_y = sheet[ghost_atom][1] % r_length
        image = filter(lambda i: abs(i[0] - ghost_x) < 1e-2 and
                       abs(i[1] - ghost_y) < 1e-2, sheet)
        bond[bond_index] = old_to_new[sheet.index(image[0]) + 1 ]
        bond.sort()
        #print >> stderr, ghost_atom +1, bond[bond_index], image
    bonds_unique[repr(bond)] = bond

# Removing duplicate bonds
bonds_unique = sorted(bonds_unique.values())

sheet_new = [] 
bonds_new = []
old_to_new = {}
sheet=[]
bonds=[] 

错误发生在该行

bond[bond_index] = old_to_new[sheet.index(image[0]) + 1 ]

我很抱歉这种类型的问题已经发布了很多次,但我对 Python 还很陌生,并不完全理解字典。我是在尝试以不应该使用的方式使用字典,还是应该在不使用字典的地方使用字典? 我知道修复可能非常简单(尽管对我来说不是),如果有人能指出我正确的方向,我将不胜感激。

如果这个问题已经回答了,我再次道歉

谢谢,

克里斯。

我在 Windows 7 64 位上使用 Python IDLE 3.3.1。

【问题讨论】:

    标签: python python-idle


    【解决方案1】:

    filter() 在 python 3 中 返回一个列表,而是一个 iterable filter 对象。使用上面的next() function 来获取first 过滤的项目:

    bond[bond_index] = old_to_new[sheet.index(next(image)) + 1 ]
    

    无需将其转换为列表,因为您只使用第一个值。

    filter() 这样的可迭代对象按需产生结果,而不是一次性产生结果。如果您的sheet 列表非常大,将所有过滤结果放入列表可能需要很长时间和大量内存,但filter() 只需要评估您的lambda 条件直到one 来自sheet 的值产生True 结果以产生一个输出。您告诉filter() 对象通过sheet 扫描第一个值,方法是将其传递给next() 函数。您可以多次这样做以获取多个值,或者使用其他可迭代的工具来完成更复杂的事情; itertools library 充满了这样的工具。 Python for loop 是另一个这样的工具,它也一个一个地从一个可迭代对象中获取值。

    如果您必须可以同时访问所有过滤结果,因为您必须随意索引结果(例如,因为这一次您的算法需要访问索引 223,索引 17 然后索引 42) 仅 然后 将可迭代对象转换为列表,使用 list():

    image = list(filter(lambda i: ..., sheet))
    

    访问有序值序列的任何值的能力称为随机访问list 就是这样一个序列,tuple 或 numpy 数组也是如此。可迭代对象提供随机访问。

    【讨论】:

    • 很难记住这种语言什么时候是面向对象的,什么时候是程序性的——为什么不用iterable.next() 而不是next(iterable)
    • @Basic:.next() 是钩子方法,next() 是标准库 API。像len() vs. .__len__()str() vs. .__str__() 等。在 Python 3 中,.next() 方法已重命名为 .__next__();不给它一个特殊的方法名是错误的。 next()(该函数)还允许您指定在引发 StopIteration 时返回的默认值。
    • 如果这个答案能更多地解释过滤结果和列表之间的差异,以及如何相互转换,那将会更有帮助。此答案假定用户熟悉 Python 中列表和可迭代对象的语义,OP 明确提到他不完全理解字典,这暗示他也不完全理解列表或可迭代对象。
    • @kevr:同意,事实证明这个问题比我当时预期的更受欢迎。我已经编辑了答案以更详细地介绍可迭代对象。
    【解决方案2】:

    filter 条件之前使用list,那么它可以正常工作。对我来说,它解决了这个问题。

    例如

    list(filter(lambda x: x%2!=0, mylist))
    

    而不是

    filter(lambda x: x%2!=0, mylist)
    

    【讨论】:

    • 来自 Martijn 和 K. Kotagram 的回答——python 3 中的过滤器返回可迭代,而不是列表; list(iterable) 将其转换为列表,因此它是可下标的
    • 照做了,错误依旧,没用
    【解决方案3】:
    image = list(filter(lambda i: abs(i[0] - ghost_x) < 1e-2 and abs(i[1] - ghost_y) < 1e-2, sheet))
    

    【讨论】:

      猜你喜欢
      • 2016-07-20
      • 2021-08-15
      • 1970-01-01
      • 2020-08-18
      • 2017-07-15
      • 2021-10-01
      • 2019-12-07
      • 2012-01-09
      • 2021-11-23
      相关资源
      最近更新 更多