Python словарь, который отображает строки в набор строк?
Я хотел бы сделать словарь Python со строками в виде ключей и наборов строк в качестве значений. Например: { "crackers" : ["crunchy", "salty"] }
Это должен быть набор, а не список.
Однако, когда я пытаюсь сделать следующее:
word_dict = dict()
word_dict["foo"] = set()
word_dict["foo"] = word_dict["foo"].add("baz")
word_dict["foo"] = word_dict["foo"].add("bang")
Я получаю:
Traceback (most recent call last):
File "process_input.py", line 56, in <module>
test()
File "process_input.py", line 51, in test
word_dict["foo"] = word_dict["foo"].add("bang")
AttributeError: 'NoneType' object has no attribute 'add'
Если я это сделаю:
word_dict = dict()
myset = set()
myset.add("bar")
word_dict["foo"] = myset
myset.add("bang")
word_dict["foo"] = myset
for key, value in word_dict:
print key,
print value
Я получаю:
Traceback (most recent call last):
File "process_input.py", line 61, in <module>
test()
File "process_input.py", line 58, in test
for key, value in word_dict:
ValueError: too many values to unpack
Какие-нибудь советы о том, как заставить Python делать то, что мне нужно? Я являюсь промежуточным пользователем Python (или так я думал, пока не столкнулся с этой проблемой.)
Ответы
Ответ 1
set.add()
не возвращает новый set
, он изменяет set
он вызывается. Используйте его следующим образом:
word_dict = dict()
word_dict["foo"] = set()
word_dict["foo"].add("baz")
word_dict["foo"].add("bang")
Кроме того, если вы используете цикл for
для итерации по dict, вы выполняете итерацию по клавишам:
for key in word_dict:
print key, word_dict[key]
В качестве альтернативы вы можете выполнять итерацию по word_dict.items()
или word_dict.iteritems()
:
for key, value in word_dict.items():
print key, value
Ответ 2
from collections import defaultdict
word_dict = defaultdict(set)
word_dict['banana'].add('yellow')
word_dict['banana'].add('brown')
word_dict['apple'].add('red')
word_dict['apple'].add('green')
for key,values in word_dict.iteritems():
print "%s: %s" % (key, values)
Ответ 3
Когда вы говорите word_dict["foo"].add("baz")
, вы добавляете "baz" к установленному word_dict [ "foo" ].
Функция возвращает None
- обновление набора является побочным эффектом. Итак,
word_dict["foo"] = word_dict["foo"].add("baz")
в конечном итоге устанавливает word_dict["foo"]
в None
.
Просто word_dict["foo"].add("baz")
будет правильным.
Во втором сценарии, когда вы говорите
for key, value in word_dict:
вы столкнулись с ошибкой, потому что правильный синтаксис
for key in word_dict:
чтобы перебрать только клавиши в word_dict
. В этой ситуации вы хотите
for key,value in word_dict.iteritems():
вместо.
Ответ 4
Try:
word_dict = dict()
myset = set()
myset.add("bar")
word_dict["foo"] = myset
myset.add("bang")
word_dict["foo"] = myset
for key in word_dict:
print key, word_dict[key]
Похоже, что стандартный итератор словаря возвращает только key
, но не кортеж.
Доказательство:
>>> d = { 'test': 1 }
>>> for k, v in d: print k, v
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
>>> for k in d: print d[k]
...
1
Ответ 5
Проблема заключается в следующем:
word_dict["foo"] = word_dict["foo"].add("baz")
Когда вы вызываете word_dict["foo"].add("baz")
, вы мутируете набор, на который ссылается word_dict["foo"]
, и эта операция возвращает None
. Поэтому, читая ваше утверждение справа налево, вы добавляете "baz" к набору, на который ссылается word_dict["foo"]
, а затем устанавливаете результат этой операции (то есть None
) на word_dict["foo"]
.
Итак, чтобы сделать эту работу так, как вы ожидаете, просто удалите word_dict["foo"] =
из вашего утверждения.
Словари итерации по своим ключам по умолчанию, поэтому ValueError вы пытаетесь это сделать:
for key, value in word_dict:
Что происходит, так это то, что итерация на word_dict возвращает только ключ (скажем, "foo" ), который вы затем пытаетесь распаковать в переменные key
и value
. Распаковка "foo" дает вам "f", "o" и "o", что является слишком большим значением для двух переменных и, следовательно, ValueError.
Как утверждали другие, вы хотите перебирать пары слова-словаря так:
for key, value in word_dict.iteritems ():