неожиданный результат при использовании понимания списка в булевых списках Python - PullRequest
0 голосов
/ 25 мая 2018
r=[True, False,True,False, False]
print([i for i in r if str(r[i])=="True"])

этот код дает следующий неожиданный результат: [False, False, False]

Почему это поведение?Я бы ожидал: [True, True]

Ответы [ 5 ]

0 голосов
/ 25 мая 2018

Жак Гаудин прав, что вы индексируете с логическим значением.Однако еще более простой вариант кода будет выглядеть так:

print([i for i in r if str(i)=="True"])

или, конечно:

print([i for i in r if i])
0 голосов
/ 25 мая 2018

Это должно дать вам желаемый результат

r=[True, False,True,False, False]
print([i for i in r if str(i)=="True"])

i относится к отдельным элементам в массиве.

0 голосов
/ 25 мая 2018

Вы имели в виду str(i).

С вашим исходным кодом,

  • на первой итерации, i равно True и как Trueимеет целочисленное значение 1, r[i] будет r[1], что неверно.Условие if не выполняется.

  • на второй итерации, i равно False, а поскольку False имеет целочисленное значение 0, r[i] будетr[0], что правда.Условие if успешно выполняется, и к результату добавляется i (то есть False).

0 голосов
/ 25 мая 2018

Вы используете i двумя различными способами:

  • В index список (r[i])
  • И в качестве переменной итерациив понимании списка [i for i in items]

r[i] обычно завершается ошибкой, если i не является целым числом - списки могут быть проиндексированы только через целые числа.Тем не менее, логические значения являются особым случаем в Python, bool на самом деле является подклассом int:

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

Именно поэтому это даже «работает» и дает вам удивительные результаты.

Поскольку нет необходимости использовать индексирование списков при понимании списков, это то, что вы, вероятно, хотели написать:

>>> print([i for i in r if str(i) == "True"])
[True, True]

Также обратите внимание, что неявное приведение происходитздесь, в отличие от других ранее предложенных ответов:

Python этого не делает. не"переводит r [i] в ​​r [int (i)]".

Давайте посмотрим на строку "1".Он с радостью применит это значение к int, если вы попросите:

>>> int("1")
1

Но, тем не менее, использование "1" для индексации списка никогда не сработает:

>>> lst = ['a', 'b', 'c']
>>> lst["1"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str

Ваш примертолько «работает», потому что bool на самом деле является подклассом int, а True, следовательно, действительно является целым числом, насколько это касается Python.

0 голосов
/ 25 мая 2018

i - логическое значение со значением True или False.Если вы используете его в качестве индекса в r[i], вы получите либо r[0], либо r[1], поскольку bool является подклассом int.

Вы можете изобразить это как r[int(i)] и int(True) == 1, int(False) == 0.

Что вы, вероятно, имеете в виду:

print([i for i in range(len(r)) if str(r[i])=="True"])

, где i являетсяцелое число или:

print([i for i in r if str(i)=="True"])

, где i - логическое значение.

Обратите внимание, что если i - логическое значение, в if str(i) == "True" мало смысла.Более краткий способ написания:

print([i for i in r if i])

или даже использование встроенной функции фильтра :

it = filter(None, r)
print(list(it))
...