Estou tentando pegar um arquivo parecido com este
AAA x 111
AAB x 111
AAA x 112
AAC x 123
...
E use um dicionário para que a saída fique assim
{AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
Isso é o que eu tentei
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()
Eu continuo recebendo um TypeError: unhashable type: 'list'
. Eu sei que as chaves em um dicionário não podem ser listas, mas estou tentando transformar meu valor em uma lista, não na chave. Estou me perguntando se cometi um erro em algum lugar.
fonte
Os valores hash são apenas números inteiros usados para comparar as chaves do dicionário durante uma pesquisa no dicionário rapidamente.
Internamente, o
hash()
método chama o__hash__()
método de um objeto que é definido por padrão para qualquer objeto.Converter uma lista aninhada em um conjunto
Isso acontece por causa da lista dentro de uma lista que é uma lista que não pode ser hash. Que pode ser resolvido convertendo as listas aninhadas internas em uma tupla ,
Hashing explicitamente de uma lista aninhada
fonte
Você está tentando usar
k
(que é uma lista) como uma chave parad
. As listas são mutáveis e não podem ser usadas como chaves de ditado.Além disso, você nunca inicializa as listas no dicionário, por causa desta linha:
Que deve ser:
Que deveria ser:
fonte
A razão pela qual você está recebendo a
unhashable type: 'list'
exceção é porque osk = list[0:j]
conjuntosk
são uma "fatia" da lista, que é logicamente outra lista, geralmente mais curta. O que você precisa é obter apenas o primeiro item da lista, escrito assimk = list[0]
. O mesmo para ov = list[j + 1:]
qual deve ser apenasv = list[2]
para o terceiro elemento da lista retornado da chamada parareadline.split(" ")
.Percebi vários outros problemas prováveis com o código, dos quais mencionarei alguns. Um grande problema é que você não deseja (re) inicializar
d
comd = {}
para cada linha lida no loop. Outra é geralmente não é uma boa ideia nomear variáveis da mesma forma que qualquer um dos tipos integrados, porque isso o impedirá de acessar um deles se precisar - e é confuso para outros que estão acostumados com o nomes que designam um desses itens padrão. Por esse motivo, você deve renomear sua variávellist
variável para evitar problemas como esse.Aqui está uma versão funcional do seu com essas alterações, também simplifiquei a
if
expressão de instrução que você tinha, que verifica se a chave já está no dicionário - há maneiras implícitas ainda mais curtas de fazer esse tipo de coisa, mas usando um condicional declaração está bem por enquanto.Resultado:
fonte
O
TypeError
está acontecendo porquek
é uma lista, uma vez que é criada a partir de uma fatia de outra lista com a linhak = list[0:j]
. Provavelmente deve ser algo assimk = ' '.join(list[0:j])
, então você tem uma string em vez.Além disso, sua
if
afirmação está incorreta, conforme observado pela resposta de Jesse, que deveria serif k not in d
ouif not k in d
(eu prefiro a última).Você também está limpando seu dicionário em cada iteração, já que está
d = {}
dentro de seufor
loop.Observe que você também não deve usar
list
oufile
como nomes de variáveis, pois estará mascarando os builtins.Aqui está como eu reescreveria seu código:
O
dict.setdefault()
método acima substitui aif k not in d
lógica do seu código.fonte
not k in d
pode confundir um novato(not k) in d
, pois , emborak not in d
não tenha ambigüidadenot in
listada como um operador .!a.contains(b)
.not in
pode ser mais pythônico, só acho o conceito de operadores de duas palavras mais confuso do que usar um inverso em uma expressão booleana.fonte