Это Pythonic, чтобы использовать bools в качестве int? - PullRequest
63 голосов
/ 04 июля 2010

False эквивалентно 0 и True эквивалентно 1, поэтому возможно сделать что-то вроде этого:

def bool_to_str(value):
    """value should be a bool"""
    return ['No', 'Yes'][value]

bool_to_str(True)

Обратите внимание, что значение равно bool, но используется как int.

Это такой вид использования Pythonic или его следует избегать?

Ответы [ 7 ]

160 голосов
/ 04 июля 2010

Я буду странным голосом (так как все ответы осуждают использование факта, что False == 0 и True == 1, как язык гарантирует), поскольку я утверждаю, что использование этого факта для упрощения вашего кода прекрасно.

Исторически логические операции true / false имели тенденцию просто использовать 0 для false и 1 для true; в течение жизненного цикла Python 2.2 Гвидо заметил, что слишком много модулей начинаются с назначений, таких как false = 0; true = 1, и это приводит к шаблону и бесполезному изменению (последнее, потому что заглавные буквы true и false были повсюду - некоторые использовали заглавные буквы, некоторые строчные, некоторые заглавные) и поэтому представили подкласс bool из int и его константы True и False.

В то время произошел некоторый откат, так как многие из нас боялись, что новый тип и константы будут использоваться новичками Python для ограничения возможностей языка, но Гвидо был непреклонен в том, что мы просто пессимистичны : никто бы никогда не понял Python так плохо, например, чтобы избежать совершенно естественного использования False и True в качестве индексов списков, или для суммирования, или других таких совершенно ясных и полезных идиом.

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

Борясь с течением такого недоразумения, я призываю всех использовать Python в качестве Python , , а не , пытаясь навязать его в форму других языков, функциональность и предпочтительный стиль которых довольно разные. В Python True и False на 99,9% похожи на 1 и 0, отличаясь исключительно в их str(...) (и, следовательно, repr(...)) форме - для каждые другие операции, кроме строковых, просто не стесняйтесь использовать их без искажений. Это касается индексации, арифметики, битовых операций и т. Д. И т. Д. И т. Д.

143 голосов
/ 29 июля 2011

Я с Алексом. False==0 и True==1, и в этом нет ничего плохого.

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

def bool_to_str(value):
  return 'Yes' if value else 'No'

Таким образом, не требуется, чтобы аргумент был на самом деле bool - так же, как if x: ... принимает любой тип для x, функция bool_to_str() должна делать правильные вещи, когда передается None, строка, список или 3.14.

37 голосов
/ 04 июля 2010

наверняка:

def bool_to_str(value):
    "value should be a bool"
    return 'Yes' if value else 'No'

более читабельно.

13 голосов
/ 05 июля 2010

Ваш код кажется неточным в некоторых случаях:

>>> def bool_to_str(value):
...     """value should be a bool"""
...     return ['No', 'Yes'][value]
...
>>> bool_to_str(-2)
'No'

И я рекомендую вам использовать только условный оператор для удобства чтения:

def bool_to_str(value):
    """value should be a bool"""
    return "Yes" if value else "No"
5 голосов
/ 04 июля 2010

На самом деле это особенность языка, что False == 0 и True == 1 (это не зависит от реализации): Является ли False == 0 и True == 1 в Python деталями реализации илигарантируется ли это языком?

Однако я согласен с большинством других ответов: есть более удобочитаемые способы получения того же результата, что и ['No', 'Yes'][value], с использованием … if value else … или из словаря, который имеет соответствующие преимущества, намекая и заявляя, что value является логическим значением.

Кроме того, … if value else … следует обычному соглашению, что non-0 - это True: он также работаеткогда value == -2 (значение Истина), как намекнул георгин.Подходы со списком и диктом в данном случае не столь надежны, поэтому я бы не рекомендовал их.

1 голос
/ 05 июля 2010

Использование bool в качестве int вполне нормально, потому что bool является подклассом int.

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True

О вашем коде: поместить его в однострочную функцию, подобную этой, сверху.Читатели должны найти источник вашей функции или документацию и прочитать ее (название функции говорит вам немного).Это прерывает поток.Просто поместите его в строку и не используйте список (созданный во время выполнения), используйте кортеж (созданный во время компиляции, если значения являются константами).Пример:

print foo, bar, num_things, ("OK", "Too many!)[num_things > max_things]
0 голосов
/ 23 декабря 2016

Лично я думаю, что это зависит от того, как вы хотите использовать этот факт, вот два примера

  1. Просто просто используйте логическое значение, так как условное выражение хорошо.Люди делают это все время.

    a = 0
    if a:
        do something
    
  2. Однако, если вы хотите посчитать, сколько элементов успешно, код может быть не очень дружелюбным для чтения другими людьми.

    def succeed(val):
        if do_something(val):
            return True
        else:
            return False
    
    count = 0
    values = [some values to process]
    for val in values:
        count += succeed(val)
    

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

all_successful = all([succeed(val) for val in values])
at_least_one_successful = any([succeed(val) for val in values])
total_number_of_successful = sum([succeed(val) for val in values])
...