J'essaie de prendre un fichier qui ressemble à ceci "Aucun 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], ...}
Voici 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 continue à obtenir un `TypeError : unhashable type : 'list'`. Je sais que les clés d'un dictionnaire ne peuvent pas être des listes, mais j'essaie de faire de ma valeur une liste et non la clé. Je me demande si je n'ai pas fait une erreur quelque part.
Comme indiqué par les autres réponses, l'erreur est due à k = list[0:j]
, où votre clé est convertie en liste. Une chose que vous pourriez essayer est de retravailler votre code pour tirer profit de la fonction 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']}
Notez que si vous utilisez Python 3.x, vous devrez faire un petit ajustement pour que cela fonctionne correctement. Si vous ouvrez le fichier avec rb
, vous devrez utiliser line = line.split(b'x' ;)
(qui s'assure que vous divisez l'octet avec le bon type de chaîne). Vous pouvez également ouvrir le fichier en utilisant with open('filename.txt' ;, 'rU' ;) as f:
(ou même with open('filename.txt' ;, 'r' ;) as f:
) et cela devrait fonctionner correctement.
Vous essayez d'utiliser k
(qui est une liste) comme clé pour d
. Les listes sont mutables et ne peuvent pas être utilisées comme clés de dict.
De plus, vous n'initialiserez jamais les listes dans le dictionnaire, à cause de cette ligne :
if k not in d == False:
Qui devrait être :
if k not in d == True:
Ce qui devrait être en fait :
if k not in d:
Le TypeError
se produit parce que k
est une liste, puisqu'il est créé en utilisant une tranche d'une autre liste avec la ligne k = list[0:j]
. Cela devrait probablement être quelque chose comme "k = ' ; ' ;.join(list[0:j])`", de sorte que vous ayez une chaîne de caractères à la place.
En plus de cela, votre instruction " si " est incorrecte, comme l'a noté la réponse de Jesse, qui devrait lire " si k n'est pas dans d " ou " si ce n'est pas k dans d " (je préfère cette dernière option).
Vous effacez également votre dictionnaire à chaque itération puisque vous avez d = {}
à l'intérieur de votre boucle for
.
Notez que vous ne devriez pas non plus utiliser list
ou file
comme noms de variables, puisque vous allez masquer des builtins.
Voici comment je réécrirais votre code :
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:]))
La méthode dict.setdefault()
ci-dessus remplace la logique if k not in d
de votre code.