Ответ 1
Вы можете повернуть его:
>>> d1 = {"yes": [1,2,3], "no": [4]}
а затем "инвертировать" этот словарь:
>>> d2 = {value:key for key in d1 for value in d1[key]}
>>> d2
{1: 'yes', 2: 'yes', 3: 'yes', 4: 'no'}
Мне интересно, есть ли способ заполнить словарь таким образом, чтобы у вас было сопоставление нескольких ключей с тем же значением, которое было бы менее подробным, чем скажем:
d = {1:'yes', 2:'yes', 3:'yes', 4:'no'}
Я думаю что-то вроде:
d = {*(1,2,3):'yes', 4:'no'}
который, очевидно, является синтаксической ошибкой.
Есть ли простой способ сделать это без слишком много запутывания? (Я не играю в гольф кода, но мне также не нужно писать по-разному одну и ту же вещь снова и снова. Однако любые ответы, связанные с кодом-гольф, будут оценены, так как Code-Golf является awesome =]).
Edit
Я, вероятно, выбрал плохой пример. Это то, что я пытаюсь сделать:
d = {*('READY', 95): 'GPLR2_95', 'CHARGING': 'GPLR3_99', 'PROTECTION': 'GPLR3_100', 'CONNECTED': 'GPLR3_101', 'ERROR':'GPLR3_102'}
Я бы ожидал, что это будет расширяться до:
d = {'READY':'GPLR2_95', 95: 'GPLR2_95', ...}
Edit- > Edit
Я знаю, что это глупо и совершенно ненужно, но моя цель - сделать это выражение на одной строке. Это, очевидно, не должно ограничивать ответы и писать код только потому, что он подходит по одной строке, это глупо. Но я пишу константу постоянного уровня модуля, что было бы неплохо, если бы это был один лайнер.
Вы можете повернуть его:
>>> d1 = {"yes": [1,2,3], "no": [4]}
а затем "инвертировать" этот словарь:
>>> d2 = {value:key for key in d1 for value in d1[key]}
>>> d2
{1: 'yes', 2: 'yes', 3: 'yes', 4: 'no'}
Как насчет:
501 $ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = {"q":1}
>>> print a
{'q': 1}
>>> a["q"]
1
>>> a["r"] = a["s"] = a["t"] = 2
>>> a
{'q': 1, 's': 2, 'r': 2, 't': 2}
>>>
Код гольфа?
yesindices = [1,2,3,22,34,33]
noindices = [4,8,9]
dict (zip(yesindices, ['yes' for i in yesindices]) + zip(noindices, ['no' for i in noindices]))
дает
{1: 'yes', 2: 'yes', 3: 'yes', 4: 'no', 33: 'yes', 8: 'no', 9: 'no', 34: 'yes', 22: 'yes'}
d = {'READY': 'GPLR2_95',
95: 'GPLR2_95',
'CHARGING': 'GPLR3_99',
'PROTECTION': 'GPLR3_100',
'CONNECTED': 'GPLR3_101',
'ERROR':'GPLR3_102'}
Что не так, если сломать это на несколько строк (как указано выше)? Сохраняет ли точка сохранение или сохранение вертикального пространства? Что-то еще?
Кстати, действительно странно иметь ключи, которые представляют собой сочетание чисел и строк.
note: Я написал это как ответ вместо комментария, потому что я хотел показать форматированный код на нескольких строках.
Для вашего случая
dict([(_, 'yes') for _ in range(1,4)], **{4:'no'})
И если вам нужны несколько ключей для 'yes'
и 'no'
>>> from itertools import chain
>>> dict(chain([(_, 'yes') for _ in range(1,4)], [(_, 'no') for _ in range(4, 10)]))
{1: 'yes', 2: 'yes', 3: 'yes', 4: 'no', 5: 'no', 6: 'no', 7: 'no', 8: 'no', 9: 'no'}
Не так здорово, но работает.
dict((x, {4: 'no'}.get(x, 'yes')) for x in range(1, 5))
Или в 3.x:
{x: {4: 'no'}.get(x, 'yes') for x in range(1, 5)}