2017-01-02 2 views
0

Итак, я возился с удалением нецелых чисел из списка в Python (очень интересный материал). Я наткнулся на вопрос со следующим кодом, который я не могу показаться, чтобы решить:Проблема при удалении false из списка с isinstance

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

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

Я пытаюсь удалить все не ИНТ элементов в списке, но приведенный выше код не удаляет значение False.

Что я хочу: [1, 2, 3]

Что я получаю: [1, 2, 3, False]

Любая помощь выяснить это будет высоко ценится!

+0

Проверьте http://pythontutor.com –

+1

False - это значение, которое равно 0, что является целым числом! – Li357

+0

'False' внутренне представлен как целое число 0. Фактически' False == 0' является 'True', но' False is 0' is not. Использовать оператор 'is' для удаления' False'. – DyZ

ответ

3

В Python bool подкласс int:

>>> 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) 

Один чистый способ исправить это с помощью списка понимание.

4

Ваш вопрос в том, что boolявляется подклассом int:

>>> issubclass(bool, int) 
True 

Поэтому все Bools является Интсом (где фальшь 0 и истина 1) и может быть использована для индексации и тому подобного. Вместо этого вы можете проверить type(item) is bool.

1

Проверьте, не является ли элемент экземпляром чего-либо. Проверьте свой тип непосредственно:

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

[1, 2, 3]

1

Вы делаете две ошибки здесь:

  • Если предположить isinstance работы с bool (другие объяснили, как 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

Bool является подклассом Int, кроме того типа() и isinstance() не следует путать. Это связано с тем, что до того, как boolean стал его собственным классом «1» и «0», были представлены True и False соответственно.

В результате вы должны использовать type() из-за наследования.

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

Это неразрушающий модифицированный список, потому что иногда изменения списка вы перебор может вызвать ошибки или быть болью по крайней мере.

Смежные вопросы