[Tutor] list objects are unhashable

Alan Gauld alan.gauld at btinternet.com
Tue Jul 1 10:37:36 CEST 2008


"Norman Khine" <norman at khine.net> wrote

> Here is the 'full' code as such which gets the data from the files.

Unfortunately trying to read this is still difficult since we don't
know what the structure of x, horizontal_criterias, 
vertical_criterias,
or brains is like.

>         ## Classify the users
>         table = {}
>         table[('', '')] = 0
>         for x in horizontal_criterias:
>             table[(x['id'], '')] = 0
>         for y in vertical_criterias:
>             table[('', y['id'])] = 0
>         for x in horizontal_criterias:
>             x = x['id']

You select a collection of some sort and replace it with a value
from the collection. Is that really what you want to do? You don't
do it for y...

>             for y in vertical_criterias:
>                 table[(x, y['id'])] = 0

It would be just as readable IMHO to just use

          table[ x['id'],y['id'] ] = 0

>         for brain in brains:
>             x = getattr(brain, horizontal)
>             if isinstance(x, list):
>                 for item in x:
>                     x = item

And here you replace the list x with it' first item.
You could just do

x = x[0]

>             else:
>                 x

And this does nothing useful whatsoever. It just
siilently evaluates x.

>             y = getattr(brain, vertical)
>             if isinstance(y, list):
>                 for item in y:
>                     y = item
>             else:
>                 y

Same comments apply

>             if x and y and (x, y) in table:
>                 table[(x, y)] += 1
>                 table[(x, '')] += 1
>                 table[('', y)] += 1
>                 table[('', '')] += 1
>
>
> table is a dictionary, which returns, for example:
>
> {   ('', ''): 1,
>     ('', 'fr'): 0,
>     ('airport-car-parking', ''): 2,
>     ('airport-car-parking', 'fr'): 0,
>     ('air-taxi-operators', ''): 1,
>     ('air-taxi-operators', 'fr'): 0,
>      ...
>     ('worldwide-attractions-and-ticket-agents', ''): 0,
>     ('worldwide-attractions-and-ticket-agents', 'fr'): 0,

>From this I suggest you rename your variable from x and y
to something meaningful like facility and country. That
might make your code more meaningful to read.

> The output is something like:
> country |airport-car|air-taxi-operators|airlines-schedule| total
> ---------------------------------------------------------------
> france  |0     |0        |0 |0
> uk |2     |0        |0 |2
> us |0          |0        |0 |0
> ---------------------------------------------------------------
> total |2     |0                 |0 |2
> ---------------------------------------------------------------
>
> What I can't seem to figure out is how to do a cumulative sum for 
> each record, for example, my files contain:

Frankly I'd use a database. Just load the data into it using Python.
Then execute SQL querioes to get the counts etc.

>             if isinstance(x, list):
>                 for item in x:
>                     x = item
>     pp.pprint(x)
>             else:
>
> Which is correct, but the table only counts the first item of the 
> tuple.

Isn't that because you replace x with the first element of x?

Alan G. 




More information about the Tutor mailing list