首页 > 解决方案 > 遍历函数内部的列表时,为什么 0 不是 0.0?

问题描述

我正在尝试解决一个问题,其中我必须从列表中删除零(00.0)并将它们添加到列表的末尾(附加的零可以是 a 0,不必是0.0)。但问题是我不能删除False. 我以为我终于通过使用is而不是解决了我的问题,==但由于某种原因它不起作用:

arr = [9,0.0,0,9,1,2,0,1,0,1,0.0,3,0,1,9,0,0,0,0,9]
def move_zeros(array):
    temp = array.copy()
    j = 0
    for p, i in enumerate(array):
        if i is 0 or i is 0.0:
            del temp[p - j]
            j += 1
            temp.append(0)
    return temp

print(move_zeros(arr))

我试过在if语句中加上括号,但结果是一样的。它删除了所有0但由于某种原因它不会删除0.0。结果:

[9, 0.0, 9, 1, 2, 1, 1, 0.0, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0]

我重写了函数,但在函数之外,由于某种原因它可以工作:

array = [1, 0, 2, False, 0.0, 4]
for p, i in enumerate(array):
    if i is 0 or i is 0.0:
        del temp[p - j]
        j += 1
        temp.append(0)

这里的结果是我所期望的:

[1, 2, False, 4, 0, 0]

为什么在函数外执行时浮点零被删除,但调用函数时,语句move_zeros中无法识别浮点数?if

标签: pythonlistfloating-point

解决方案


你只处理floatsints- 如果值不是 0,你可以从你的输入构造一个新列表:

arr = [9,0.0,0,9,1,2,0,1,0,1,0.0,3,0,1,9,0,0,0,0,9]

def move_zeros(array):
    len_arr = len(array)
    return ([ x for x in array if x != 0.0]+[0]*len_arr)[:len_arr]

# equivalent non-listcomprehension but simple for loop
def m_z(arr):
    k = []
    tmp = []
    for e in arr:
        if e/1.0 != 0.0:
            k.append(e)
        else:
            tmp.append(0)
    return k+tmp

    print(move_zeros(arr))

输出:

[9, 9, 1, 2, 1, 1, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

如果x仅是整数0并且-0可以导致0.0 - 如果x是浮点数,则仅0.0并且-0.0可以导致 0.0 - 只是不要将它们放入输出中。.copy()不需要,因为列表理解已经为您复制了。

检查整数和is工作是因为 python 缓存从 -5 到 256 左右的整数 - 它们都得到相同的结果id(),因此is“似乎”工作。

is用于None支票或如果您知道自己在做什么,切勿用于数字。

如果您想保持非 ( ìnt,float) 不变,您也可以检查:

arr = [9,0.0,0,False,9,1,2,0,1,0,1,0.0,3,0,1,9,0,0,0,0,9]

def move_zeros(array):
    len_arr = len(array)
    return ([ x for x in array if type(x) not in {int,float} or 
             x != 0.0]+[0]*len_arr)[:len_arr]

# [9, False, 9, 1, 2, 1, 1, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

阅读更多:


小型健全性检查:

k = 365
i = 365 // 5 * 5  # if you do i = 365 only, they are ==/is True, this way: they are not

for elem in [0,False,k]:
    for olem in [0,False,i]:     
        print(f"{str(elem):>8} is {str(olem):<10}:   {str(elem is olem):<10} ")
        print(f"{str(elem):>8} == {str(olem):<10}:   {str(elem == olem):<10} ")

输出:

       0 is 0         :   True       
       0 == 0         :   True       
       0 is False     :   False      
       0 == False     :   True       
       0 is 365       :   False      
       0 == 365       :   False      
   False is 0         :   False      
   False == 0         :   True       
   False is False     :   True       
   False == False     :   True       
   False is 365       :   False      
   False == 365       :   False      
     365 is 0         :   False      
     365 == 0         :   False      
     365 is False     :   False      
     365 == False     :   False      
     365 is 365       :   False      # k is i
     365 == 365       :   True       # k == i

推荐阅读