2017-01-02 15 views
0

だから、私はPythonのリストから非整数を取り除くことを面倒していました(非常にエキサイティングなもの)。私は、リスト内のすべての非整数の項目を削除しようとしているが、上記のコードはFalseを削除しませんisinstanceでリストからfalseを取り除くときの問題

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

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

:私は解決することができないよう、次のコードで問題に出くわしました。私が欲しいもの

[1, 2, 3, False]

をこのアウトを考え出すすべてのヘルプははるかに高く評価されるだろう:私は取得しています何[1, 2, 3]

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

これは、あなたがより洗練されたチェックが必要であることを意味します:Pythonで

+0

http://pythontutor.com –

+1

Falseは値で、0です(整数)。 – Li357

+0

'False'は内部的には整数の0として表されます。実際、' False == 0'は 'True'ですが、' False is 0'はありません。 'False'を削除するには、演算子' is'を使用します。 – DyZ

答えて

3

boolintのサブクラスです。たとえば、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) 

一つのきれいな方法は、リストの内包表記を使用することです。

4

あなたの問題は、boolintのサブクラスあるとされています

>>> issubclass(bool, int) 
True 

したがって、すべてのboolsはint型です(偽は0で、真が1である。)とインデックスと、そのようなを使用することができます。代わりにtype(item) is boolをテストできます。

1

アイテムが何かのインスタンスであるかどうかをチェックします。

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

を[1、2、3]

1

あなたはここに2つのエラーをしている:直接その型をチェックbool(他の人とisinstance作品を想定し

  • がどのように説明しました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] 
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] 
0

ブールは、(さらに入力のIntのサブクラスである)とでisinstance()を混同してはなりません。これは、ブール値がそれ自身のクラスになる前に、それぞれ「1」と「0」がTrueとFalseを表すからです。

その結果、継承のためにtype()を使用する必要があります。

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

、時にはあなたはを反復しているリストを変更すると、エラーが発生したり、少なくとも痛みをすることができますので、これは非破壊修正リストです。

関連する問題