Error: unhashable type: 'dict_keys', how to solve?

0

I have a code that accesses a CSV file through a function. I created a second function to change the name of the column header (changeName) and to not have to call it several times changing the parameters of "columnIngles" and "columnPortugues" - a call for each column -, I created a support function ( changeNameName) that takes the keys and values from a dictionary and passes as an argument in the main function call (changeName).

That is, it is a function that calls another function using the keys and values of a dictionary as parameters.

It happens that it gives the error "TypeError: unhashable type: 'dict_keys'" and I can not solve it, I tried to convert to list and frozenset but it was unsuccessful.

Any ideas how to solve it?

CSV access script:

import unicodecsv

def lerCsv(arquivo):
    with open(arquivo, 'rb') as dados:
        dicionario = unicodecsv.DictReader(dados)
        return list(dicionario)

envolvimentoDiario = lerCsv('envolvimento_diario.csv')

Script with functions to change the keys of the columns:

envolvimentoNomesColunas = {'acct': 'id_conta', 'utc_date': 'data'}

chaves = envolvimentoNomesColunas.keys()
valores = envolvimentoNomesColunas.values()


def alterarNomeSuporte(arquivo):
    for coluna in arquivo:
        alterarNome(arquivo, chaves, valores)

def alterarNome(arquivo, colunaIngles, colunaPortugues):
    for coluna in arquivo:
        coluna[colunaPortugues] = coluna[colunaIngles] (colunaPortugues) cujos valores são iguais ao da colunaIngles
        del[coluna[colunaIngles]]

alterarNomeSuporte(envolvimentoDiario)
print (envolvimentoDiario[0])

Thank you!

    
asked by anonymous 26.11.2017 / 02:01

1 answer

0

With frozenset should work yes - the correct thing would be to do in these lines:

chaves = envolvimentoNomesColunas.keys()
valores = envolvimentoNomesColunas.values()

passing to

chaves = frozenset(envolvimentoNomesColunas.keys())
valores = frozenset(envolvimentoNomesColunas.values())

So the function "changeName" jpa receives the data as frozenset and uses it in all places.

As I disabused in the comments, the names of your variables are bad - to the point that it is very difficult to follow your code. The suggestion is that the variable name always remember in fact its contents. (And a lighter suggestion is that function names in Python variables are usually in minuscule, separated by "_". This is a style suggestion and each one can do as you please, but one of the reasons Python has adopted this style is what most people prefer to read.)

But then, the error you had after switching the key search to frozenset is precisely why when you create the dictionary, you should convert the key to frozenset as well. If the key is a string, it will never be the same as the frozenset we tried to fetch.

For keys to be frozensets, you only have to do this when creating each dictionary:

def lerCsv(arquivo):
    with open(arquivo, 'rb') as dados:
        leitor = unicodecsv.DictReader(dados)
        return [{frozenset(chave): frozenset(valor) for chave, valor in linha.items()}  for linha in leitor]

However, this code, which will create the dictionaries correctly, indicates that what you are trying to do has some other problem - since the keys read by CSV Reader will always be a single string. The lists that gave rise to your unhashable key error will not be found in your dictionary even now that we have normalized key types.

In other words, even with these settings you should still have a "KeyError" error, but with this code style I can not keep track of what you are actually trying to do. My suggestion is that you use the debugger (pdb), or insert some prints in your code to understand how the existing keys and values you want to replace - and possibly it will be possible to leave everything as strings even.

(Incidentally, if you are using Python3, it does not have to be a "unicodecsv", just the csv normal, from the default library)

    
26.11.2017 / 03:18