Опитвам се да взема файл, който изглежда по следния начин
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 = list[0:j]
, където ключът е преобразуван в списък. Едно нещо, което можете да опитате, е да преработите кода си, за да се възползвате от функцията split
:
# Using with ensures that the file is properly closed when you're done
with open('filename.txt', 'rb') as f:
d = {}
# Here we use readlines() to split the file into a list where each element is a line
for line in f.readlines():
# Now we split the file on `x`, since the part before the x will be
# the key and the part after the value
line = line.split('x')
# Take the line parts and strip out the spaces, assigning them to the variables
# Once you get a bit more comfortable, this works as well:
# key, value = [x.strip() for x in line]
key = line[0].strip()
value = line[1].strip()
# Now we check if the dictionary contains the key; if so, append the new value,
# and if not, make a new list that contains the current value
# (For future reference, this is a great place for a defaultdict :)
if key in d:
d[key].append(value)
else:
d[key] = [value]
print d
# {'AAA': ['111', '112'], 'AAC': ['123'], 'AAB': ['111']}
Обърнете внимание, че ако използвате Python 3.x, ще трябва да направите малка корекция, за да заработи правилно. Ако отворите файла с rb
, ще трябва да използвате line = line.split(b'x')
(което гарантира, че разделяте байта с правилния тип низ). Можете също така да отворите файла с помощта на with open('filename.txt', 'rU') as f:
(или дори with open('filename.txt', 'r') as f:
) и той би трябвало да работи добре.
Опитвате се да използвате k
(което е списък) като ключ за d
. Списъците са променливи и не могат да се използват като ключове за дикти.
Също така, вие никога не инициализирате списъците в речника, заради този ред:
if k not in d == False:
Което трябва да бъде:
if k not in d == True:
Което всъщност трябва да бъде:
if k not in d:
Грешката TypeError
се появява, защото k
е списък, тъй като е създаден с помощта на парче от друг списък с реда k = list[0:j]
. Това вероятно трябва да бъде нещо като k = ' '.join(list[0:j])
, така че вместо това имате низ.
Освен това вашият оператор if
е неправилен, както е отбелязано в отговора на Jesse's, който трябва да се чете 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
от вашия код.