Как предполагали другие, маловероятно, что использование 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
. Приведенный выше код **
превращает результат следующего выражения в набор аргументов ключевого слова, которые передаются вызываемой функции. Это, безусловно, надежный способ создания словарей, и люди, кажется, по крайней мере принимают эту идиому, но я подозреваю, что некоторые могут посчитать ее Unpythonic. </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 этого не говорят. Что ж, в некоторых случаях это правда. Я предполагаю, что Гвидо дал нам толкование словаря, чтобы был один очевидный способ сделать это.