Python: TypeError: tipo não chicotável: 'list'

I'estou tentando pegar um arquivo que se parece com este "ninguém 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], ...}



Isto é o que a I'já 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 chaves em um dicionário podem't ser listas, mas eu'estou tentando fazer meu valor em uma lista, não a chave. I'estou me perguntando se eu cometi um erro em algum lugar.
Solução

Como indicado pelas outras respostas, o erro é devido a k = list[0:j], onde sua chave é convertida em uma lista. Uma coisa que você poderia tentar é refazer seu código para aproveitar a função `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']}

Note que se você estiver usando o Python 3.x, você'terá que fazer um pequeno ajuste para que ele funcione corretamente. Se você abrir o arquivo com rb, você'precisará utilizar line = line.split(b'x') (o que garante que você está dividindo o byte com o tipo apropriado de string). Você também pode abrir o arquivo utilizando with open('filename.txt', 'rU') como f: (ou mesmo with open('filename.txt', 'r') como f:) e deve funcionar bem.

Comentários (3)

Você'está tentando usar k (que é uma lista) como uma chave para d. Lists are mutable and can't be used as dict keys.

Além disso, você'nunca está inicializando as listas no dicionário, por causa desta linha:

if k not in d == False:

O que deveria ser:

if k not in d == True:

O que na verdade deveria ser:

if k not in d:
Comentários (1)

O TypeError' está acontecendo porquek' é uma lista, já que é criado utilizando uma fatia de outra lista com a linha k = list[0:j]. Isto provavelmente deve ser algo como k = ' '.join(list[0:j]), então você tem uma string no lugar.

Além disso, a sua declaração 'se' está incorreta, como notado pela resposta de Jesse's, que deve ler-se 'se k não em d' ou 'se não k em d' (eu prefiro a última).

Você também está limpando seu dicionário em cada iteração, já que você tem d = {} dentro do seu loop `for'.

Note que você também não deve estar utilizando list ou file como nomes de variáveis, já que você estará mascarando builtins.

Aqui está como eu reescreveria o seu código:

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:]))

O método dict.setdefault() acima substitui o método if k not in d logic do seu código.

Comentários (3)