Подтвердить что ты не робот

Есть ли законное использование списка [True], список [False] в Python?

Так как True и False являются экземплярами int, в Python допустимо следующее:

>>> l = [0, 1, 2]
>>> l[False]
0
>>> l[True]
1

Я понимаю, почему это происходит. Тем не менее, я нахожу это поведение немного неожиданным и может привести к жестким ошибкам. Это, конечно, укусил меня пару раз.

Может ли кто-нибудь подумать о законном использовании индексирующих списков с True или False?

4b9b3361

Ответ 1

В прошлом некоторые люди использовали это поведение для создания условного выражения бедных <:

['foo', 'bar'][eggs > 5]  # produces 'bar' when eggs is 6 or higher, 'foo' otherwise

Однако с надлежащим условным выражением, добавленным к языку в Python 2.5, это очень неодобрительно, по причинам вы заявляете: полагаясь на логические значения, являющиеся подклассом целых чисел, слишком "магическим" и нечитаемым для сопровождающего.

Итак, если вы не играете в кодекс (намеренно создаете очень компактный и неясный код), используйте

'bar' if eggs > 5 else 'foo'

который имеет дополнительное преимущество в том, что два выражения, которые выбираются между ними, оцениваются лениво; если eggs > 5 является ложным, выражение перед if никогда не выполняется.

Ответ 2

Если вы недоумеваете, почему bool является допустимым аргументом индекса: это просто для согласованности с тем, что bool является подклассом int, а в Python он - числовой тип.

Если вы спрашиваете, почему bool является числовым типом в первую очередь, тогда вы должны понимать, что bool не присутствовал в старых версиях Python, а люди использовали int вместо этого.

Я добавлю несколько исторических аргументов. Прежде всего добавление bool в python коротко описано в блоге Google Guido van Rossum (aka BDFL): История Python: история bool, True и False. Тип был добавлен через PEP 285.

PEP содержит фактические обоснования, используемые для этих решений. Я приведу некоторые из частей PEP ниже.

4) Должны ли мы стремиться устранять небулевые операции на bools  в будущем, с помощью соответствующих предупреждений, чтобы, например,   True+1 будет в конечном итоге (в Python 3000) незаконным?

= > Нет.

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


6) Должно ли bool наследовать от int?

= > Да.

В идеальном мире bool может быть лучше реализована как отдельный целочисленный тип, который знает, как выполнять смешанный режим арифметика. Однако наследование bool из int облегчает (отчасти со всех кодов C, вызывающих PyInt_Check() будет продолжать работать - это возвращает true для  подклассы int). Кроме того, я считаю, что это правильно с точки зрения  заменимость: код, которому требуется int, может быть передан bool и он будет вести себя так же, как 0 или 1. Код, требующий  bool может не работать, когда ему присваивается int; например, 3 и 4  0, но оба 3 и 4 являются истинными, если рассматривать их как истину  значения.


Поскольку bool наследуется от int, True+1 действителен и равен 2, и скоро. Это важно для обратной совместимости: потому что сравнения и т.д. в настоящее время возвращают целочисленные значения, нет способ показать, что использует существующие приложения из этих значения.


Из-за обратной совместимости, тип bool испытывает недостаток  свойства, которые некоторые хотели бы видеть. Например,  допускаются операции с одним или двумя аргументами bool, обработка  False как 0 и True как 1. Кроме того, bool может использоваться как последовательность  индекс.

Я не вижу в этом проблемы, и я не хочу развиваться  язык в этом направлении. Я не считаю, что  более строгая интерпретация "Booleanness" делает язык любым  понятнее.


Резюме

  • Обратная совместимость: было много кода, который уже использовал int 0 и 1 для представления False и True, а некоторые из них использовали эти значения в числовых вычислениях.
  • Не было большого смысла иметь тип "нетекстовый" bool
  • Многим людям в сообществе Python нужны эти функции.
  • BDFL так сказал.

Ответ 3

Часто бывают лучшие способы, но у булевых индексов есть свои возможности. Я использовал их, когда хочу преобразовать логический результат в нечто более читаемое человеком:

test_result = run_test()
log.info("The test %s." % ('Failed', 'Passed')[test_result])