Подтвердить что ты не робот

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 (или так я думал, пока не столкнулся с этой проблемой.)

4b9b3361

Ответ 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 ():