TypeError: unhashable type: 'dict' when attempting to hash list - advice sought
Ben Finney
ben+python at benfinney.id.au
Sat Aug 29 23:04:24 EDT 2015
kbtyo <ahlusar.ahluwalia at gmail.com> writes:
> I am using Jupyter Notebook and Python 3.4.
Thank you for saying so! It is not always required, but when it matters,
this information is important to state up front.
> I have a data structure in the format, (type list):
>
> [{'AccountNumber': N,
> 'Amount': '0',
> 'Answer': '12:00:00 PM',
> 'ID': None,
> 'Type': 'WriteLetters',
> 'Amount': '10',
> {'AccountNumber': Y,
> 'Amount': '0',
> 'Answer': ' 12:00:00 PM',
> 'ID': None,
> 'Type': 'Transfer',
> 'Amount': '2'}]
>
> The end goal is to write this out to CSV.
So that assumes that *every* item will be a mapping with all the same
keys. CSV is limited to a sequence of “records” which all have the same
fields in the same order.
> The list comprehension "data" is to maintain the integrity of the
> column headers and the values for each new instance of the data
> structure (where the keys in the dictionary are the headers and values
> - row instances). The keys in this specific data structure are meant
> to check if there is a value instance, and if there is not - place an
> ''.
>
[…]
> for row in results:
> data = [row.get(index, '') for index in results]
The ‘for’ statement iterates over ‘results’, getting an item each time.
The name ‘row’ is bound to each item in turn.
Then, each time through the ‘for’ loop, you iterate *again* over
‘results’. The name ‘index’ is bound to each item.
You then attempt to use the dict (each item from ‘results’ is itself a
dict) as a key into that same dict. A dict is not a valid key; it is not
a “hashable type” i.e. a type with a fixed value, that can produce a
hash of the value).
So you're getting dicts and attempting to use those dicts as keys into
dicts. That will give the error “TypeError: unhashable type: 'dict'”.
I think what you want is not items from the original sequence, but the
keys from the mapping::
for input_record in results:
output_record = [input_record.get(key, "") for key in input_record]
But you're then throwing away the constructed list, since you do nothing
with it before the end of the loop.
> writer.writerow(data)
This statement occurs only *after* all the items from ‘results’ have
been iterated. You will only have the most recent constructed row.
Perhaps you want::
for input_record in results:
output_record = [input_record.get(key, "") for key in input_record]
writer.writerow(output_record)
--
\ “An idea isn't responsible for the people who believe in it.” |
`\ —Donald Robert Perry Marquis |
_o__) |
Ben Finney
More information about the Python-list
mailing list