使用isinstance从列表中删除false时出现问题

时间:2017-01-02 23:08:33

标签: python list python-3.x boolean

所以,我正在搞乱从Python中的列表中删除非整数(非常令人兴奋的东西)。我遇到了以下代码无法解决的问题:

list_a = ["a", 1, 2, 3, False, [1, 2, 3]]

for item in list_a:
    if not isinstance(item, int):
        list_a.remove(item)

我试图删除列表中的所有非int项,但上面的代码不会删除False。

我想要的是:[1, 2, 3]

我得到了什么:[1, 2, 3, False]

任何帮助解决这个问题都会非常感激!

6 个答案:

答案 0 :(得分:4)

您的问题是bool int的子类:

>>> issubclass(bool, int)
True

因此,所有bool都是整数(其中False为0且True为1)并且可以用于索引等。您可以改为测试type(item) is bool

答案 1 :(得分:3)

在Python中,boolint的子类:

>>> isinstance(True, int)
True
>>> isinstance(True, bool)
True

这意味着您需要更精确的检查。例如,您可以检查type(item) == int

有关背景信息,请参阅PEP 285

    6) Should bool inherit from int?

    => Yes.

       In an ideal world, bool might be better implemented as a
       separate integer type that knows how to perform mixed-mode
       arithmetic.  However, inheriting bool from int eases the
       implementation enormously (in part since all C code that calls
       PyInt_Check() will continue to work -- this returns true for
       subclasses of int).  Also, I believe this is right in terms of
       substitutability: code that requires an int can be fed a bool
       and it will behave the same as 0 or 1.  Code that requires a
       bool may not work when it is given an int; for example, 3 & 4
       is 0, but both 3 and 4 are true when considered as truth
       values.

另一个不相关的问题是,您在迭代时修改列表。阅读Modifying list while iterating及其中的链接。

这导致代码中的细微错误。例如,它无法从以下列表中删除"b"(尝试它!):

list_a = ["a", "b", 1, 2, 3]

for item in list_a:
    if not isinstance(item, int):
        list_a.remove(item)

解决此问题的一种简洁方法是使用列表推导。

答案 2 :(得分:1)

检查项目是否是某个实例。直接检查其类型:

[x for x in list_a if type(x)==int]
  

[1,2,3]

答案 3 :(得分:1)

你在这里犯了两个错误:

  • 假设isinstancebool一起使用(其他人已解释bool实际上int的子类如何。
  • 在迭代时更改列表

这可能是需要明确使用type(val) == int进行测试的情况之一:

list_a = ["a", 1, 2, 3, False, [1, 2, 3]]

for item in list_a[:]:
    if not type(item) == int:
        list_a.remove(item)

产生想要的结果;注意list_a如何与[:]一起复制,以确保我们尽可能地删除它的所有内容。

在理解形式中,这更漂亮:

res = [i for i in list_a if type(i) == int]

答案 4 :(得分:1)

明确的方法。

list_a = ["a", 1, 2, 3, False, [1, 2, 3]]
list_b = []
for item in list_a:
    if isinstance(item, int) and not isinstance(item, bool):
        list_b.append(item)
print list_b

输出

[1, 2, 3]

答案 5 :(得分:0)

Bool是Int的子类,而且type()和isinstance()不应该混淆。这是因为在boolean成为它自己的类之前" 1" s和" 0" s分别代表True和False。

因此,由于继承,你应该使用type()。

def f(randomList):
    result = []
    for elem in randomList:
        if type(elem)==int:
            result.append(elem)
    return result

这是一个非破坏性修改列表,因为有时修改您正在迭代的列表可能会导致错误或至少造成痛苦。