Recibo este error en mi código unhashable type: 'list'

Tengo un archivo de texto con esta entrada:

hokejistov hokej
strelena strela
trener trenuje

Quiero dividir palabras en 2 filas. La primera fila consistirá en las primeras palabras. Y la segunda fila consistirá en segundas palabras. Entonces necesito dividir las palabras en signos. Esta parte está funcionando pero luego necesito usar el diccionario (mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9,'r':10, 'l':11, 'n':12, 'a':13, 'u':14}).

En la salida quiero obtener esto:

first = [[1, 2, 3, 4, 5, 6, 7, 8, 2, 9], [7, 8, 10, 4, 11, 4, 12, 13], [8, 10, 4, 12, 4, 10]]
second = [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]

Este es mi código

data = [line.strip() for line in open("mamradhokej.txt",'r')]
mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9, 
        'r':10, 'l':11, 'n':12, 'a':13, 'u':14}

first = [[word.lower() for word in text.split()[0]]for text in data]
second = [[word.lower() for word in text.split()[1]]for text in data]

print(first)
print(second)

map(mapka.get, first)
[mapka[k] for k in first] #here i am getting Type error: unhashable type: 'list'.
2
kamco 5 oct. 2019 a las 17:51

3 respuestas

La mejor respuesta

¿Por qué recibes este error?

Las claves del diccionario deben ser objetos hashables.

Para que un objeto sea hashable, debe ser una instancia de una clase que implemente los métodos __eq__ y __hash__.

Los objetos de tipo list no son hashaable.

La razón por la que recibe este error es porque first es una lista de listas.

Nota al margen: hashable no significa inmutable en python

Solución

Necesita una iteración anidada:

first_output = [[mapka[letter] for letter in word] for word in first] 

Y de manera similar para second. También puede recorrer primero y segundo para evitar la duplicación de código

3
Dimitrios Dedoussis 5 oct. 2019 a las 15:26

Como el mapka se aplicará sobre el carácter , debe iterar al nivel del personaje.

En Python iterando una cadena , resulta en iterar sobre los caracteres.

Entonces esto debería funcionar:

data = ["hokejistov hokej", "strelena strela", "trener trenuje"] 
second = [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]
mapka = {'h':1,'o':2,'k':3, 'e':4, 'j':5, 'i':6, 's':7, 't':8,'v':9, 
    'r':10, 'l':11, 'n':12, 'a':13, 'u':14}

first = [[word.lower() for word in text.split()[0]]for text in data]
second = [[word.lower() for word in text.split()[1]]for text in data]

print([[mapka[letter] for letter in word] for word in first])
print([[mapka[letter] for letter in word] for word in second])
0
John Sig 5 oct. 2019 a las 15:27

Aquí hay una solución solo con listas:

# pretend to read your file
data = ["hokejistov hokej","strelena strela","trener trenuje"]

# a dictionary is not strictly needed here
mapka = "hokejistvrlnau"

# convert lines to columns
columns = []
for line in data:
    for i,word in enumerate(line.split()):
        try:
            columns[i].append(word)
        except IndexError:
            columns.append([word])

print(columns) # [['hokejistov', 'strelena', 'trener'], ['hokej', 'strela', 'trenuje']]

# look up each letter
for column in columns:
    print( [ [mapka.index(letter)+1  for letter in word] for word in column] )

# [[1, 2, 3, 4, 5, 6, 7, 8, 2, 9], [7, 8, 10, 4, 11, 4, 12, 13], [8, 10, 4, 12, 4, 10]]
# [[1, 2, 3, 4, 5], [7, 8, 10, 4, 11, 13], [8, 10, 4, 12, 14, 5, 4]]
0
handle 5 oct. 2019 a las 15:29
58249430