Пытаюсь взять файл, который выглядит так:
AAA x 111
AAB x 111
AAA x 112
AAC x 123
...
И используйте словарь, чтобы результат выглядел так
{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
Это то, что я пробовал
file = open("filename.txt", "r")
readline = file.readline().rstrip()
while readline!= "":
list = []
list = readline.split(" ")
j = list.index("x")
k = list[0:j]
v = list[j + 1:]
d = {}
if k not in d == False:
d[k] = []
d[k].append(v)
readline = file.readline().rstrip()
Я продолжаю получать TypeError: unhashable type: 'list'
. Я знаю, что ключи в словаре не могут быть списками, но я пытаюсь превратить свое значение в список, а не в ключ. Интересно, не ошибся ли я где-нибудь.
источник
Вы пытаетесь использовать
k
(это список) в качестве ключа дляd
. Списки изменяемы и не могут использоваться в качестве ключей dict.Кроме того, вы никогда не инициализируете списки в словаре из-за этой строки:
if k not in d == False:
Что должно быть:
if k not in d == True:
Что на самом деле должно быть:
if k not in d:
источник
Причина вы получаете
unhashable type: 'list'
исключение, потому чтоk = list[0:j]
наборыk
быть «срез» из списка, который является логически другим, часто короче, списком. Что вам нужно, так это получить только первый элемент в списке, написанный таким образомk = list[0]
. То же самое,v = list[j + 1:]
что иv = list[2]
для третьего элемента списка, возвращаемого при вызовеreadline.split(" ")
.Я заметил несколько других вероятных проблем с кодом, из которых я упомяну несколько. Большой один вы не хотите (ре) инициализации
d
сd = {}
для каждой строки прочитать в цикле. Во-вторых, обычно не рекомендуется называть переменные так же, как любые встроенные типы, потому что это помешает вам получить доступ к одному из них, если он вам нужен - и это сбивает с толку других, которые привыкли к имена, обозначающие один из этих стандартных предметов. По этой причине вам следует переименовать вашу переменную вlist
другое имя, чтобы избежать подобных проблем.Вот ваша рабочая версия с этими изменениями. Я также заменил
if
выражение оператора, которое вы использовали для проверки, был ли ключ уже в словаре, и теперь используюsetdefault()
метод словаря, чтобы сделать то же самое немного более лаконично.d = {} with open("nameerror.txt", "r") as file: line = file.readline().rstrip() while line: lst = line.split() # Split into sequence like ['AAA', 'x', '111']. k, _, v = lst[:3] # Get first and third items. d.setdefault(k, []).append(v) line = file.readline().rstrip() print('d: {}'.format(d))
Выход:
источник
Это
TypeError
происходит потому, чтоk
это список, поскольку он создается с использованием фрагмента из другого списка со строкойk = list[0:j]
. Вероятно, это должно быть что-то вродеk = ' '.join(list[0:j])
, так что вместо этого у вас есть строка.В дополнение к этому ваше
if
утверждение неверно, как указано в ответе Джесси, который следует читатьif k not in d
илиif not k in d
(я предпочитаю последнее).Вы также очищаете свой словарь на каждой итерации, поскольку у вас
d = {}
внутриfor
цикла.Обратите внимание, что вы также не должны использовать
list
или вfile
качестве имен переменных, поскольку вы будете маскировать встроенные функции.Вот как я бы переписал ваш код:
d = {} with open("filename.txt", "r") as input_file: for line in input_file: fields = line.split() j = fields.index("x") k = " ".join(fields[:j]) d.setdefault(k, []).append(" ".join(fields[j+1:]))
Приведенный
dict.setdefault()
выше метод заменяетif k not in d
логику вашего кода.источник
not k in d
может запутать новичка , как(not k) in d
, в то время какk not in d
не имеет двусмысленностьnot in
указанный как оператор .!a.contains(b)
.not in
может быть более питоническим, я просто нахожу концепцию двух операторов более запутанной, чем использование инверсии для логического выражения.python 3.2 with open("d://test.txt") as f: k=(((i.split("\n"))[0].rstrip()).split() for i in f.readlines()) d={} for i,_,v in k: d.setdefault(i,[]).append(v)
источник