2017-07-27 295 views
-2

首先,我已经看过这些帖子上的同一主题:类型错误:只能加入一个可迭代的Python错误

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 这是什么意思,以及如何解决呢?

+0

你需要检查你的缩进 – Harrichael

+0

我改变了我的缩进,但仍然得到错误... – Bobawob

+0

'people [one:two] = -1' < - 你正在尝试给列表片分配一个整数。 – zwer

回答

0

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

people[one:two] = [-1] 

将取代与单一元素-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 
>>> 

people[one:two] = [-1] * (two-one) 
您可以在交互式解释很方便地测试了这一点
0

要直接解决您所问的问题,您正尝试将单个元素分配给切片(这需要可迭代)。在你的榜样清理了一些东西,你可能会做一些这样的:

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) 
0

它一般是一个好主意,除去从列表中,你遍历项目,它可能会导致意外结果,如果你不小心。见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] 
0

除了我在评论中提到的错误,如果你正在寻找这样做在一个更简单的方式,试试这个:

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 
+0

@Downvoter - 建设性的批评是值得欢迎的。 – zwer

+0

@holdenweb - 考虑到列表不改变长度,'insert'完全安全 - 即使所有的'-1'条目都在列表的尾部,'list.insert()'允许在最后的指数。 – zwer

+0

已将Downvote删除 – holdenweb

相关问题