kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 Keenan
Keenan
Question

Python: TypeError: unhashable type: 'list'

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.

74 2012-12-02T23:49:20+00:00 3
 Georgy
Georgy
Întrebarea editată 21 ianuarie 2019 в 9:28
Programare
python
list
dictionary
typeerror
Această întrebare are 1 răspuns în engleză, pentru a le citi, vă rugăm să vă logați.
Solution / Answer
 RocketDonkey
RocketDonkey
3 decembrie 2012 в 12:01
2012-12-03T00:01:40+00:00
Mai mult
Sursă
Editează
#17879162

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.

 RocketDonkey
RocketDonkey
Răspuns editat 3 decembrie 2012 в 12:53
43
0
Jesse  the Game
Jesse the Game
2 decembrie 2012 в 11:52
2012-12-02T23:52:14+00:00
Mai mult
Sursă
Editează
#17879160

Î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:
Jesse  the Game
Jesse the Game
Răspuns editat 2 decembrie 2012 в 11:58
15
0
Andrew Clark
Andrew Clark
2 decembrie 2012 в 11:55
2012-12-02T23:55:46+00:00
Mai mult
Sursă
Editează
#17879161

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ă.

0
0
Comunități asemănătoare 1
Python România
Python România
125 utilizatori
Comunitatea pasionaților de Python din România.
Deschide telegram
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
BG
DA
DE
EL
ES
FR
ID
IT
JA
KO
LV
NL
NO
PT
RO
RU
SL
TR
ZH
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire