I'm încearcă să ia un fișier care arată ca aceasta
AAA x 111
AAB x 111
AAA x 112
AAC x 123
...
Și folosiți un dicționar pentru ca rezultatul să arate astfel
{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
Aceasta este ceea ce am încercat
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()
Continui să primesc un TypeError: unhashable type: 'list'
. Știu că cheile dintr-un dicționar nu pot fi liste, dar eu încerc să transform valoarea mea într-o listă, nu în cheie. Mă întreb dacă nu cumva am făcut o greșeală undeva.
Așa cum au indicat și celelalte răspunsuri, eroarea se datorează k = list[0:j]
, unde cheia este convertită într-o listă. Un lucru pe care l-ați putea încerca este să vă refaceți codul pentru a profita de funcția 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']}
Rețineți că, dacă utilizați Python 3.x, va trebui să faceți o mică ajustare pentru a o face să funcționeze corect. Dacă deschideți fișierul cu rb
, va trebui să folosiți line = line.split(b'x')
(care se asigură că împărțiți octetul cu tipul corect de șir de caractere). Puteți, de asemenea, să deschideți fișierul folosind with open('nume fișier.txt', 'rU') ca f:
(sau chiar with open('nume fișier.txt', 'r') ca f:
) și ar trebui să funcționeze bine.
Încerci să folosești k
(care este o listă) ca o cheie pentru d
. Listele sunt mutabile și nu pot fi folosite ca chei dict.
De asemenea, nu inițializați niciodată listele din dicționar, din cauza acestei linii:
if k not in d == False:
Care ar trebui să fie:
if k not in d == True:
Care ar trebui să fie de fapt:
if k not in d:
Eroarea TypeError
se întâmplă deoarece k
este o listă, deoarece este creată folosind o felie dintr-o altă listă cu linia k = list[0:j]
. Probabil că ar trebui să fie ceva de genul k = ' '.join(list[0:j])
, astfel încât să aveți în schimb un șir de caractere.
În plus, afirmația dvs. if
este incorectă, așa cum a fost observat de răspunsul lui Jesse's, care ar trebui să fie if k not in d
sau if not k in d
(îl prefer pe cel din urmă).
De asemenea, vă ștergeți dicționarul la fiecare iterație, deoarece aveți d = {}
în interiorul buclei for
.
Rețineți că nu ar trebui să folosiți list
sau file
ca nume de variabile, deoarece veți masca elementele construite.
Iată cum aș rescrie eu codul dumneavoastră:
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:]))
Metoda dict.setdefault()
de mai sus înlocuiește logica if k not in d
din codul dumneavoastră.