Чтобы объявить несколько переменных одновременно, я бы сделал:
a, b = True, False
Но если бы мне пришлось объявить гораздо больше переменных, это становилось все менее и менее элегантным:
a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True
Есть ли лучший / элегантный / удобный способ сделать это?
Это должно быть очень просто, но если я использую список или кортеж для хранения переменных, как мне подойти, чтобы быть полезным, поскольку:
aList = [a,b]
Недействительно, мне нужно будет сделать:
a, b = True, True
Или что мне не хватает?
python
variables
declaration
Труфа
источник
источник
Ответы:
Как предполагали другие, маловероятно, что использование 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 этого не говорят. Что ж, в некоторых случаях это правда. Я предполагаю, что Гвидо дал нам толкование словаря, чтобы был один очевидный способ сделать это.
источник
['a', 'b', 'c']
можно сократить доlist('abc')
, что вдохновляетdef truth_values(trues, falses): d = dict.from_keys(list(trues), True); d.update(dict.from_keys(list(falses), False)); return d
использовать какvalues = truth_values("abc", "de")
a, b, c, d, e, g, h, i, j = (True,)*9 f = False
источник
(d,)
создает кортеж из одного элемента, который является типом последовательности. Типы последовательностей , помимо других операций, поддерживают сложение и умножение.a, b, c = ([],)*3
не создают 3 список экземпляров , но делаетa
,b
иc
указывая на один экземпляр.a, b, c = ([] for i in range(3))
. источник . Для единообразия вы также можете использовать вариант этого ответа, то естьa,b,c,d,e,g,h,i,j = (True for i in range(9))
f=(False i in range(1))
.Используйте список / словарь или определите свой собственный класс для инкапсуляции того, что вы определяете, но если вам нужны все эти переменные, вы можете сделать:
a = b = c = d = e = g = h = i = j = True f = False
источник
Это разработка @ Jeff M и моих комментариев.
Когда вы это сделаете:
Работает с упаковкой и распаковкой кортежей. Вы можете разделить этапы упаковки и распаковки:
Первая строка создает кортеж с именем
_
, состоящий из двух элементов, первый со значением,c
а второй со значениемd
. Вторая строка распаковывает_
кортеж в переменныеa
иb
. Это разбивает вашу одну огромную строку:a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True, True, True, True
На две более мелкие строки:
_ = True, True, True, True, True, False, True, True, True, True a, b, c, d, e, f, g, h, i, j = _
Это даст вам тот же результат, что и первая строка (включая то же исключение, если вы добавляете значения или переменные в одну часть, но забываете обновить другую). Однако в этом конкретном случае ответ Яна, пожалуй, лучший.
Если у вас есть список значений, вы все равно можете их распаковать. Вам просто нужно сначала преобразовать его в кортеж. Например, следующее будет присвоить значение от 0 до 9 каждому из
a
доj
, соответственно:a, b, c, d, e, f, g, h, i, j = tuple(range(10))
РЕДАКТИРОВАТЬ: изящный трюк, чтобы назначить все из них как истинные, кроме элемента 5 (переменная
f
):a, b, c, d, e, f, g, h, i, j = tuple(x != 5 for x in range(10))
источник
Когда люди предлагают «использовать список, кортеж или другую структуру данных», они говорят, что, когда у вас много разных значений, которые вас волнуют, называть их все отдельно, поскольку локальные переменные могут быть не лучшим способом делать вещи.
Вместо этого вы можете собрать их вместе в более крупную структуру данных, которая может храниться в одной локальной переменной.
intuited показал, как для этого можно использовать словарь, а Крис Лутц показал, как использовать кортеж для временного хранения перед распаковкой в отдельные переменные, но еще один вариант, который следует рассмотреть, - это использовать
collections.namedtuple
для более постоянного связывания значений.Итак, вы можете сделать что-то вроде:
# Define the attributes of our named tuple from collections import namedtuple DataHolder = namedtuple("DataHolder", "a b c d e f g") # Store our data data = DataHolder(True, True, True, True, True, False, True) # Retrieve our data print(data) print(data.a, data.f)
Мы надеемся, что в реальном коде будут использоваться более значимые имена, чем «DataHolder» и, конечно, буквы алфавита.
источник
DataHolder
просто определение становится более подробным.В чем собственно проблема?
Если вам действительно нужно или вы хотите 10 a , b , c , d , e , f , g , h , i , j , не будет другой возможности, в то или иное время, написать a, написать b и написать c . ....
Если значения все разные, вы должны будете написать, например,
a = 12 b= 'sun' c = A() #(where A is a class) d = range(1,102,5) e = (line in filehandler if line.rstrip()) f = 0,12358 g = True h = random.choice i = re.compile('^(!= ab).+?<span>') j = [78,89,90,0]
то есть определение «переменных» индивидуально.
Или, используя другое письмо, не нужно использовать
_
:a,b,c,d,e,f,g,h,i,j =\ 12,'sun',A(),range(1,102,5),\ (line for line in filehandler if line.rstrip()),\ 0.12358,True,random.choice,\ re.compile('^(!= ab).+?<span>'),[78,89,90,0]
или
a,b,c,d,e,f,g,h,i,j =\ (12,'sun',A(),range(1,102,5), (line for line in filehandler if line.rstrip()), 0.12358,True,random.choice, re.compile('^(!= ab).+?<span>'),[78,89,90,0])
.
Если некоторые из них должны иметь одинаковое значение, проблема в том, что писать слишком долго
a, b, c, d, e, f, g, h, i, j = True, True, True, True, True, False, True ,True , True, True
?
Тогда вы можете написать:
a=b=c=d=e=g=h=i=k=j=True f = False
.
Я не понимаю, в чем именно твоя проблема. Если вы хотите написать код, вы обязаны использовать символы, необходимые для написания инструкций и определений. Что еще ?
Интересно, не является ли ваш вопрос признаком того, что вы что-то неправильно поняли.
Когда кто-то пишет
a = 10
, он не создает переменную в смысле «фрагмента памяти, значение которого может изменяться». Эта инструкция:либо запускает создание объекта типа
integer
и значения 10 и привязку имени 'a' к этому объекту в текущем пространстве именили повторно присвоить объекту 10 имя 'a' в пространстве имен (потому что 'a' был ранее привязан к другому объекту)
Я говорю это, потому что не вижу утилиты для определения 10 идентификаторов a, b, c ... указывающих на False или True. Если эти значения не меняются во время выполнения, почему 10 идентификаторов? И если они изменятся, зачем сначала определять идентификаторы? Они будут созданы при необходимости, если не определены заранее
Ваш вопрос кажется мне странным
источник
Похоже, ты неправильно подходишь к своей проблеме.
Перепишите свой код, чтобы использовать кортеж, или напишите класс для хранения всех данных.
источник
Мне нравится ответ, получивший наибольшее количество голосов; однако у него есть проблемы со списком, как показано.
>> a, b = ([0]*5,)*2 >> print b [0, 0, 0, 0, 0] >> a[0] = 1 >> print b [1, 0, 0, 0, 0]
Это подробно обсуждается (здесь) , но суть в том, что
a
иb
это один и тот же объект сa is b
возвратомTrue
(то же самое дляid(a) == id(b)
). Поэтому, если вы меняете индекс, вы меняете индекс обоихa
иb
, поскольку они связаны. Чтобы решить эту проблему, вы можете сделать (источник)>> a, b = ([0]*5 for i in range(2)) >> print b [0, 0, 0, 0, 0] >> a[0] = 1 >> print b [0, 0, 0, 0, 0]
Затем это можно использовать как вариант основного ответа, который дает "желаемые" интуитивно понятные результаты.
>> a, b, c, d, e, g, h, i = (True for i in range(9)) >> f = (False for i in range(1)) #to be pedantic
источник
В вашем случае я бы использовал YAML.
Это элегантный и профессиональный стандарт для работы с несколькими параметрами. Значения загружаются из отдельного файла. Вы можете увидеть некоторую информацию по этой ссылке:
https://keleshev.com/yaml-quick-introduction
Но его проще погуглить, так как это стандарт, о нем сотни информации, вы можете найти то, что лучше всего подходит для вашего понимания. ;)
С уважением.
источник
Как и JavaScript, вы также можете использовать несколько операторов в одной строке в Python
a = 1; b = "Hello World"; c += 3
источник