一个替代列表理解的循环。它仍然会修改列表。正如其他人所说,x is 0简化了0和{}之间的区别:In [106]: al=[0, 1, 2, False, True, 3,0,10]
In [107]: for i,x in enumerate(al):
...: if x is 0:
...: value = al.pop(i)
...: al.append(value)
...:
In [108]: al
Out[108]: [1, 2, False, True, 3, 10, 0, 0]
有这样的副作用,循环比理解更好。理解应用于:
^{pr2}$
理智。您也可以在理解中使用枚举:return [fun(x, i) for i, x in enumerate(al) if x...]
在清晰的列表理解中,列表只会出现一次;测试和返回值将只依赖于迭代变量,而不是原始列表。在
=================
请注意,0和{}通常被视为相同的。例如,期望数字的运算将False视为0,而{}则视为1。期望布尔值的函数将0视为False。在In [117]: [x+1 for x in al]
Out[117]: [1, 2, 3, 1, 2, 4, 1, 11]
In [118]: al=[0, 1, 2, False, True, 3,0,10]
In [119]: sum(al)
Out[119]: 17
==============
列表理解中带有and的示例:In [137]: [x for x in al if x==0]
Out[137]: [0, False, 0]
In [138]: [x for x in al if x==0 and x is not False]
Out[138]: [0, 0]
In [140]: [x for x in al if not (x==0 and x is not False)]
Out[140]: [1, 2, False, True, 3, 10]
==========
另一个可能的测试-str表示法:In [143]: [x for x in al if str(x)!='0']
Out[143]: [1, 2, False, True, 3, 10]
==============
您的问题不在于测试,而在于al.index(x);它同时匹配0和{},并删除第一个,而不管哪个{}通过了测试。在
具有al.index(x)的版本:In [396]: al=[1,False,2, 0,3,"b"]
In [397]: for x in al:
...: if x ==0 and x is not False:
...: al.append(al.pop(al.index(x)))
...:
In [398]: al
Out[398]: [1, 2, 0, 3, 'b', False]
带枚举的版本iIn [399]: al=[1,False,2, 0,3,"b"]
In [400]: for i,x in enumerate(al):
...: if x ==0 and x is not False:
...: al.append(al.pop(i))
...:
In [401]: al
Out[401]: [1, False, 2, 3, 'b', 0]
或者在你的职责范围内:def move_zeros(array):
[array.insert(len(array), array.pop(i)) for i,x in enumerate(array) if (x == 0 and x is not False)]
return array
In [403]: al=[1,False,2, 0,3,"b"]
In [404]: move_zeros(al)
Out[404]: [1, False, 2, 3, 'b', 0]
单独测试index:In [405]: al=[1,False,2, 0,3,"b"]
In [406]: al.index(0)
Out[406]: 1
In [407]: al.index(False)
Out[407]: 1