【问题标题】:Type error: Can only join an iterable Python-error类型错误:只能加入可迭代的 Python 错误
【发布时间】:2018-01-03 12:55:49
【问题描述】:

首先,我已经看过这些关于同一主题的帖子:

TypeError: can only join an iterable python

"Can only join an iterable" python error

"Can only iterable" Python error

python error-can only join an iterable

但遗憾的是,他们似乎都没有回答我的问题。我想列出一个列表,并按大小对所有非 -1 值进行排序,然后将 -1 返回到它们的原始位置。这是我的代码:

def sortByHeight(a):
    treeLocations = []
    for everyHeight in a:
        if everyHeight == -1:
            treeLocations.append([(len(a)-a.index(everyHeight)), (a.index(everyHeight)-1)])
            a.remove(-1)
    people = sorted(a)
    for everyPair in treeLocations:
        one = everyPair[1]
        two = everyPair[0]
        people[one:two] = -1
    return(people)

sortByHeight([-1, 150, 190, 170, -1, -1, 160, 180])

我的代码在第 11 行抛出错误:TypeError: can only assign an iterable。 这是什么意思,我该如何解决?

【问题讨论】:

  • 你需要检查你的缩进
  • 我更改了缩进,但仍然出现错误...
  • people[one:two] = -1

标签: python typeerror iterable


【解决方案1】:

除了我在评论中提到的错误之外,如果您希望以更简单的方式执行此操作,请尝试以下操作:

def sortByHeight(a):
    result = sorted(v for v in a if v != -1)  # first sort all non -1 fields
    for i, v in enumerate(a):  # enumerate and iterate over the original list
        if v == -1:  # if the current value is -1
            result.insert(i, -1)  # put it back into the sorted list at its original position
    return result

【讨论】:

  • @holdenweb - 鉴于列表不改变长度,insert 是完全安全的 - 即使所有 -1 条目都在列表的尾部,list.insert() 允许在最后一个索引之后插入。
【解决方案2】:

通常从您正在迭代的列表中删除项目是一个好主意,如果您不小心,可能会导致意外结果。见Remove items from a list while iterating。正如 John Machin 所说,这有点像锯掉你坐的树枝。 ;)

此外,从列表中删除项目效率不高:必须从头开始扫描列表,直到找到匹配的项目,然后当项目被删除时,所有后续项目都必须向下移动以填满差距。最好执行过滤操作,从您希望保留的项目中构建一个新列表。


这是执行该排序的一种相当有效的方法。诀窍是提取我们想要排序的项目,对它们进行排序,然后构建一个列表,将排序后的项目放入适当的位置。

def sortByHeight(seq):
    ''' sort `seq`, leaving any items equal to -1 in place '''
    # Extract items != -1
    a = [u for u in seq if u != -1]
    a.sort()
    it = iter(a)
    result = []
    for u in seq:
        result.append(u if u == -1 else next(it))
    return result

data = [-1, 150, 190, 170, -1, -1, 160, 180]
print(data)
result = sortByHeight(data)
print(result)

输出

[-1, 150, 190, 170, -1, -1, 160, 180]
[-1, 150, 160, 170, -1, -1, 180, 190]

【讨论】:

    【解决方案3】:

    分配的目标是列表的一个切片。如果你想给切片赋值,它必须是 Python 可以迭代的东西——列表、元组和字符串都是“可迭代”的例子。所以

    people[one:two] = [-1]
    

    将用单个元素-1 替换切片中的元素。您可以在交互式解释器中轻松测试:

    >>> my_list = [1, 2, 3, 4, 5]
    >>> my_list[2:3] = ['a', 'b', 'c']
    >>> my_list
    [1, 2, 'a', 'b', 'c', 4, 5]
    >>> my_list[2:3] = -1
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: can only assign an iterable
    >>> 
    

    如果您想用-1 替换所有元素,那么一种可能的公式是使用列表乘法来给出正确长度的序列:

    people[one:two] = [-1] * (two-one)
    

    【讨论】:

      【解决方案4】:

      为了直接解决您所询问的问题,您尝试将单个元素分配给切片(这需要可迭代)。清理示例中的一些内容,您可能会执行以下操作:

      def sortByHeight(a):
          # Get indices of all -1's
          treeLocations = [index for index, height in enumerate(a) if height == -1]
          # Get list of all others
          people = [height for height in a if height != -1]
          # Sort list of others
          people = sorted(people)
          # Re-insert -1's
          for everyIndex in treeLocations:
              people.insert(everyIndex, -1)
          return(people)
      

      【讨论】:

        猜你喜欢
        • 2015-11-15
        • 2013-11-18
        • 2020-04-18
        • 1970-01-01
        • 2021-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-10
        相关资源
        最近更新 更多