繁体   English   中英

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

[英]Issue when removing false from list with isinstance

因此,我在弄乱从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]

任何帮助弄清楚这一点将不胜感激!

您的问题是bool int的子类:

>>> issubclass(bool, int)
True

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

在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.

另一个不相关的问题是,您在迭代列表时正在修改列表。 迭代时请阅读“ 修改列表”及其中的链接。

这会在您的代码中产生一个细微的错误。 例如,它无法从以下列表中删除"b" (尝试!):

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

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

解决此问题的一种干净方法是使用列表理解。

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

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

[1,2,3]

您在这里犯了两个错误:

  • 假设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]

一种清晰的方法。

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]

Bool是Int的子类,此外,type()和isinstance()不应混淆。 这是因为在布尔值成为其自己的类之前,“ 1”和“ 0”分别表示True和False。

结果,由于继承,您应该使用type()。

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

这是一个非破坏性的已修改列表,因为有时修改您要遍历的列表可能会导致错误或至少引起痛苦。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM