J'essaye de prendre un fichier qui ressemble à ceci
AAA x 111
AAB x 111
AAA x 112
AAC x 123
...
Et utilisez un dictionnaire pour que la sortie ressemble à ceci
{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
C'est ce que j'ai essayé
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()
Je reçois toujours un TypeError: unhashable type: 'list'
. Je sais que les clés d'un dictionnaire ne peuvent pas être des listes, mais j'essaie de transformer ma valeur en liste et non en clé. Je me demande si j'ai fait une erreur quelque part.
la source
Les valeurs de hachage ne sont que des entiers qui sont utilisés pour comparer rapidement les clés du dictionnaire lors d'une recherche dans le dictionnaire.
En interne, la
hash()
méthode appelle la__hash__()
méthode d'un objet qui est définie par défaut pour n'importe quel objet.Conversion d' une liste imbriquée en un ensemble
Cela se produit à cause de la liste à l'intérieur d'une liste qui est une liste qui ne peut pas être hachée. Ce qui peut être résolu en convertissant les listes imbriquées internes en un tuple ,
Hachage explicite d' une liste imbriquée
la source
Vous essayez d'utiliser
k
(qui est une liste) comme clé pourd
. Les listes sont modifiables et ne peuvent pas être utilisées comme clés de dict.De plus, vous n'initialisez jamais les listes dans le dictionnaire, à cause de cette ligne:
Ce qui devrait être:
Ce qui devrait en fait être:
la source
La raison pour laquelle vous obtenez l'
unhashable type: 'list'
exception est que lesk = list[0:j]
ensemblesk
sont une "tranche" de la liste, qui est logiquement une autre liste, souvent plus courte. Ce dont vous avez besoin, c'est de n'obtenir que le premier élément de la liste, écrit ainsik = list[0]
. La même chose pourv = list[j + 1:]
qui devrait être justev = list[2]
pour le troisième élément de la liste renvoyée par l'appel àreadline.split(" ")
.J'ai remarqué plusieurs autres problèmes probables avec le code, dont je vais en mentionner quelques-uns. Un gros problème est que vous ne voulez pas (re) initialiser
d
avecd = {}
pour chaque ligne lue dans la boucle. Un autre est que ce n'est généralement pas une bonne idée de nommer les variables de la même manière que l'un des types intégrés, car cela vous empêchera de pouvoir accéder à l'un d'entre eux si vous en avez besoin - et cela déroutant pour les autres qui sont habitués au noms désignant l'un de ces éléments standards. Pour cette raison, vous devez renommer votre variable delist
variable différemment pour éviter de tels problèmes.Voici une version de travail de votre avec ces changements, j'ai également simplifié l'
if
expression d'instruction que vous aviez qui vérifie si la clé est déjà dans le dictionnaire - il existe des moyens implicites encore plus courts pour faire ce genre de chose, mais en utilisant un conditionnel La déclaration est très bien pour le moment.Production:
la source
Le
TypeError
se produit parce quek
c'est une liste, puisqu'elle est créée en utilisant une tranche d'une autre liste avec la lignek = list[0:j]
. Cela devrait probablement être quelque chose commek = ' '.join(list[0:j])
, donc vous avez une chaîne à la place.En plus de cela, votre
if
déclaration est incorrecte comme indiqué par la réponse de Jesse, qui devrait lireif k not in d
ouif not k in d
(je préfère ce dernier).Vous effacez également votre dictionnaire à chaque itération puisque vous avez à l'
d = {}
intérieur de votrefor
boucle.Notez que vous ne devez pas non plus utiliser
list
oufile
comme noms de variables, car vous masquerez les fonctions intégrées.Voici comment je réécrirais votre code:
La
dict.setdefault()
méthode ci-dessus remplace laif k not in d
logique de votre code.la source
not k in d
pourrait confondre un novice car(not k) in d
,k not in d
sans ambiguïténot in
est répertoriée comme opérateur .!a.contains(b)
.not in
peut être plus pythonique, je trouve juste le concept de deux opérateurs de mots plus déroutant que l'utilisation d'un inverse sur une expression booléenne.la source