Как и предполагали другие, маловероятно, что использование 10 различных локальных переменных с булевыми значениями является наилучшим способом написания вашей подпрограммы (особенно если они действительно имеют однобуквенные имена:)
В зависимости от того, что выЭто может иметь смысл использовать словарь вместо.Например, если вы хотите установить логические предустановленные значения для набора однобуквенных флагов, вы можете сделать это:
>>> flags = dict.fromkeys(["a", "b", "c"], True)
>>> flags.update(dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}
Если вы предпочитаете, вы также можете сделать это с однимоператор присваивания:
>>> flags = dict(dict.fromkeys(["a", "b", "c"], True),
... **dict.fromkeys(["d", "e"], False))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}
Второй параметр для dict
не предназначен для этого полностью: он действительно позволяет вам переопределять отдельные элементы словаря, используя ключевые аргументы, такие как d=False
.Приведенный выше код превращает результат выражения, следующего за **
, в набор ключевых аргументов , которые передаются вызываемой функции.Это, безусловно, надежный способ создания словарей, и люди, кажется, по крайней мере принимают эту идиому, но я подозреваю, что некоторые могут считать ее непифонической.</disclaimer>
Еще один подход, который, вероятно, является наиболее интуитивным, если вы будете часто использовать этот шаблон, заключается в определении ваших данных в виде списка значений флагов (True
, False
) сопоставляется с именами флагов (односимвольные строки).Затем вы преобразуете это определение данных в инвертированный словарь, который отображает имена флагов в значения флагов.Это может быть сделано довольно кратко с помощью понимания вложенного списка, но вот очень понятная реализация:
>>> def invert_dict(inverted_dict):
... elements = inverted_dict.iteritems()
... for flag_value, flag_names in elements:
... for flag_name in flag_names:
... yield flag_name, flag_value
...
>>> flags = {True: ["a", "b", "c"], False: ["d", "e"]}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}
Функция invert_dict
является функцией генератора .Он генерирует или , возвращает - это означает, что он многократно возвращает значения - пары ключ-значение.Эти пары ключ-значение являются инверсией содержимого двух элементов исходного словаря flags
.Они подаются в конструктор dict
.В этом случае конструктор dict
работает не так, как описано выше, потому что в качестве аргумента ему подают итератор , а не словарь.
Рисование на комментарии @Chris Lutz: Если выбудет действительно использовать это для односимвольных значений, вы можете на самом деле сделать
>>> flags = {True: 'abc', False: 'de'}
>>> flags = dict(invert_dict(flags))
>>> print flags
{'a': True, 'c': True, 'b': True, 'e': False, 'd': False}
Это работает, потому что строки Python повторяемые , что означает, что они могут быть перемещенычерез значение по стоимости.В случае строки значения - это отдельные символы в строке.Поэтому, когда они интерпретируются как итерируемые, как в этом случае, когда они используются в цикле for, ['a', 'b', 'c']
и 'abc'
фактически эквивалентны.Другой пример - когда они передаются в функцию, которая принимает итерацию, например tuple
.
Лично я бы не стал этого делать, потому что она не читается интуитивно: когдаЯ вижу строку, и я ожидаю, что она будет использоваться как отдельное значение, а не как список.Поэтому я смотрю на первую строку и думаю: «Хорошо, значит, есть флаг True и флаг False».Так что, хотя это возможно, я не думаю, что это путь.С другой стороны, это может помочь объяснить понятия итераторов и итераторов более четко.
Определение функции invert_dict
таким образом, что она на самом деле возвращает словарь, тоже не плохая идея;Я в основном просто не делал этого, потому что это не помогает объяснить, как работает подпрограмма.
Очевидно, что в Python 2.7 есть словарные понимания, что сделало бы чрезвычайно краткий способ реализации этой функции.,Это оставлено в качестве упражнения для читателя, поскольку у меня не установлен Python 2.7:)
Вы также можете комбинировать некоторые функции из универсального модуля itertools .Как говорится, Существует не только один способ сделать это .Подожди, люди Python не говорят этого.Ну, в любом случае это правда.Я бы предположил, что Гвидо дал нам толкование по словарю, чтобы для этого был Один очевидный способ .