将零移动到列表的末尾,同时不保留False

时间:2018-12-22 19:38:32

标签: python list

我有一些代码应该在列表中找到任何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]

6 个答案:

答案 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 TrueFalsebool的唯一实例,因此您可以使用is来将False与{{ 1}}。

0

这将保留各种非z = [] return [e for e in array if e is False or e != 0 or z.append(e)] + z 零(False00.00jDecimal(0)的顺序) ,可能在列表中。