假不应视为0

时间:2019-02-09 13:13:17

标签: python python-3.x

我必须遍历包含随机值之类的列表

["a",0,0,"b",None,"c","d",0,1,False,0,1,0,3,[],0,1,9,0,0,{},0,0,9]

,并将所有零(0)移至列表的末尾,以保留其他元素的顺序。这是我的代码:

for i in range(len(array)):
        if array[i] ==0 and array[i] is not False:
            array.append(array[i])
            array.remove(array[i])

  return array

代码工作正常,但是将“ False”视为0,因此输出与所需的不匹配。 我尝试搜索答案并将其实现到我的代码中,例如使用“ is”和“ is not”,但它们似乎对我没有用。我还能做什么?

我的输出:['a', 'b', None, 'c', 'd', 1, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],但是输出应为['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

5 个答案:

答案 0 :(得分:5)

有很多方法可以将零移动到数组的末尾。这是一种(根据需要)遍历列表并避免使用任何高级Python功能的方法。请注意,这使用了一个临时数组,因为在遍历列表时对列表中的项目进行重新排序是很不好的主意。

array = ["a",0,0,"b",None,"c","d",0,1,False,0,1,0,3,[],0,1,9,0,0,{},0,0,9]

newarray = []
for item in array:
    if item != 0 or item is False:
        newarray.append(item)
while len(newarray) < len(array):
    newarray.append(0)
array = newarray

print(array)

这给出了打印输出

['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

如果您想了解Python为什么将False等同于0,那么您应该了解FalseTruebool类型的成员,它是int的子类型。换句话说,False实际上是0,但具有特殊类型。通常这是个好主意,但您发现其中一种情况使事情变得更加复杂。

答案 1 :(得分:2)

使用过滤器的解决方案

请参阅下面的解决方案,它尝试将非零和零元素隔离开来,同时注意False要求。

data_list = ["a",0,0,"b",None,"c","d",0,1,False,0,1,0,3,[],0,1,9,0,0,{},0,0,9]

print("Input List = %s" %(data_list))
nz_list = filter(lambda x : (x != 0 or (x == 0 and x is False)), data_list)
z_list = filter(lambda x : (x == 0 and x is not False), data_list)

print("Non Zero Elements List with Order = %s" %(nz_list))
print("Zero Elements List = %s" %(z_list))

res_list = nz_list + z_list

print("Result List = %s" %(res_list))

输出:

Input List = ['a', 0, 0, 'b', None, 'c', 'd', 0, 1, False, 0, 1, 0, 3, [], 0, 1, 9, 0, 0, {}, 0, 0, 9]
Non Zero Elements List with Order = ['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9]
Zero Elements List = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Result List = ['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

答案 2 :(得分:0)

array = ["a",0,0,"b",None,"c","d",0,1,False,0,1,0,3,[],0,1,9,0,0,{},0,0,9]

for i in range(len(array)):
    if type(array[i]) is bool:
        if array[i] is False:
            array[i] = 'False'
        else:
            array[i] = 'True'
    elif array[i] is 0:
        array.append(array[i])
        array.remove(array[i])

print(array)

这可能不是确切的解决方案。但是,它可以帮助您检测布尔值,并根据列表中的字符串将其显示为“ False”或“ True”。

答案 3 :(得分:0)

您的代码有两个问题,这两个问题都不与您在0检查中与if进行比较的方式有关。确实,array[i] == 0 and array[i] is not False和较短的array[i] is 0都可以使用,尽管后者应谨慎处理。它适用于您的情况,并且适用于当前版本的Python,但不适用于较大的数字,并且可能不适用于其他版本的0(有关详细信息,请参见here

实际问题是:

  • 在迭代时修改循环时,可能会丢失元素,因为删除第i个元素,然后前进到第i+1个元素,但前进到第i+1个元素现在是第i,因此您可以跳过。不过,第二个问题可以解决这个问题。
  • 执行array.remove(array[i])时,从数组中删除与{{1}相等 即等于array[i]的第一个元素。该包括 0,因此当您在False之后点击第一个0时,您将改为删除False,而当您点击下一个False,您先删除0,依此类推。

正如在其他答案中已经指出的那样,解决此问题的最佳方法是使用显式循环或列表理解或0创建一个新数组。

答案 4 :(得分:0)

L = ['a', 0, 0, 'b', None, 'c', 'd', 0, 1, False, 0, 1, 0, 3, [], 0, 1, 9, 0, 0, {}, 0, 0, 9]

def doit(l):
    # since you want all 0 to the end there is only the need to count them
    n = 0
    for i in l:
        if i == 0 and i is not False:
            n += 1
        else:
            yield i

    # or yield [0] * n, but that yields an array of [0, 0, ...]
    for _ in [0] * n:
       yield _

na = [x for x in doit(L)]
print(L)
print(na)

输出:

['a', 0, 0, 'b', None, 'c', 'd', 0, 1, False, 0, 1, 0, 3, [], 0, 1, 9, 0, 0, {}, 0, 0, 9]
['a', 'b', None, 'c', 'd', 1, False, 1, 3, [], 1, 9, {}, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]