我有一些代码应该在列表中找到任何0
项目的位置,并将其移到后面,同时保留其他元素的顺序。
def test2(array):
try:
for n in range(len(array)):
array.append(array.pop(array.index(0)))
return array
except ValueError:
return array
此代码适用于除带有False
的列表之外的任何列表。我认为这是因为.index(0)
:还将返回列表中任何False的位置。有什么办法解决这个问题?
例如,如果array = [0,1,None,2,False,1,0]
,则输出应为[1,None,2,False,1,0,0]
使用相同的输入,我的代码将产生:[1, None, 2, 1, False, 0, 0]
答案 0 :(得分:3)
这是由于bool
是python中int
的子类的结果,因此搜索0
的第一个索引将返回False
的索引,如果它在0
之前的列表中,因为False == 0
。
您可以做的是检查列表元素是否是int
的实例,同时 not 不是bool
的实例。这样,您可以避免匹配其他虚假值(例如空容器和None
)。
def is_zero(v):
# return is instance(v, int) and v is not False and not v
# return isinstance(v, int) and not isinstance(v, bool) and not v
return type(v) in (int, float) and not v
然后您可以反向遍历lst
并就地更新。
lst = [1, 0, None, False, 0, 3, True] # For example.
for i in reversed(range(len(lst))):
if is_zero(lst[i]):
lst.append(lst.pop(i))
print(lst)
# [1, None, False, 3, True, 0, 0]
如果我没记错的话,这是摊销的线性时间复杂度。
答案 1 :(得分:2)
如果不需要创建其他列表,则可以使用列表理解:
def test2(array):
la = len(array)
return ([x for x in array if not isinstance(x,int) or x]+[0]*la)[:la]
第一部分滤除任何0整数,但允许任何非整数传递。第二部分添加(太多)零,并将结果修整回原始长度。
注意::这将创建两倍于原始列表长度的数据-因此不适用于“大”列表或少有0的列表。
用法:
k = [1,2,3,0,4,5,False,92,-3,0,1,0,0,True,[],None,True]
print(k)
print(test2(k))
输出:
[1, 2, 3, 0, 4, 5, False, 92, -3, 0, 1, 0, 0, True, [], None, True]
[1, 2, 3, 4, 5, 92, -3, 1, True, True, 0, 0, 0, 0, 0, 0, 0]
Doku:
答案 2 :(得分:1)
@coldspeed解决方案的一种变体:
array = [0, 1, None, 2, False, 1, 0]
nonzero = [x for x in array if x or x is None or isinstance(x,bool)]
nonzero + [0] * (len(array) - len(nonzero))
# [1, None, 2, False, 1, 0, 0]
答案 3 :(得分:1)
您可以将包装器与自定义__eq__
一起使用:
class Typed:
def __init__(self, val):
self.val = val
def __hash__(self):
return hash(self.val)
def __eq__(self, other):
if isinstance(other, Typed):
other = other.val
return type(self.val) is type(other) and self.val == other
然后将array.index(0)
替换为array.index(Typed(0))
-您不需要在数组本身中使用它。
将其扩展到容器(这样(0, 1)
和(False, True)
将不相等)作为练习供读者阅读。
答案 4 :(得分:0)
我认为这很简洁。谢谢大家的帮助
l = [i for i in array if isinstance(i, bool) or i!=0]
return l+[0]*(len(array)-len(l))
答案 5 :(得分:0)
Python guarantees True
和False
是bool
的唯一实例,因此您可以使用is
来将False
与{{ 1}}。
0
这将保留各种非z = []
return [e for e in array if e is False or e != 0 or z.append(e)] + z
零(False
,0
,0.0
,0j
,Decimal(0)
的顺序) ,可能在列表中。