Re: [Tutor] list objects are unhashable

2008-07-01 Thread Alan Gauld


Norman Khine [EMAIL PROTECTED] 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. 



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Kent Johnson
On Tue, Jul 1, 2008 at 3:09 AM, Norman Khine [EMAIL PROTECTED] wrote:

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

This just assigns x to the last element of the list, it doesn't
process the whole list. One possibility would be to ensure that x and
y are always lists, then use nested loops to iterate over all
combinations:
x = getattr(brain, horizontal)
if not isinstance(x, list):
  x = [x]
y = getattr(brain, vertical)
if not isinstance(y, list):
  y = [y]
for first in x:
  for second in y:
if first and second and (first, second) in table:

etc.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Alan Gauld
Kent Johnson [EMAIL PROTECTED] wrote 

   if isinstance(x, list):
   for item in x:
   x = item


This just assigns x to the last element of the list


Oops, yes, I said the first but in fact reassigning x does 
not stop the loop, it seems the loop works on a local 
copy of the original reference.


Alan G

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Norman Khine



Kent Johnson wrote:

On Tue, Jul 1, 2008 at 3:09 AM, Norman Khine [EMAIL PROTECTED] wrote:


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


This just assigns x to the last element of the list, it doesn't
process the whole list. One possibility would be to ensure that x and
y are always lists, then use nested loops to iterate over all
combinations:
x = getattr(brain, horizontal)
if not isinstance(x, list):
  x = [x]
y = getattr(brain, vertical)
if not isinstance(y, list):
  y = [y]
for first in x:
  for second in y:
if first and second and (first, second) in table:


I don't really see this clearly as I may have n'th values for 'x' and 
n'th values for 'y' so I will need to loop over all these, but without 
knowing the n'th value where to stop my loop?


Or have I missed the point ;)



etc.

Kent



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Kent Johnson
On Tue, Jul 1, 2008 at 6:27 AM, Alan Gauld [EMAIL PROTECTED] wrote:
 Kent Johnson [EMAIL PROTECTED] wrote

   if isinstance(x, list):
   for item in x:
   x = item

 This just assigns x to the last element of the list

 Oops, yes, I said the first but in fact reassigning x does not stop the
 loop, it seems the loop works on a local copy of the original reference.

Under the hood, 'for item in x' creates an iterator which has a
reference to the original list.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Alan Gauld

Norman Khine [EMAIL PROTECTED] wrote

Frankly I'd use a database. Just load the data into it using 
Python.

Then execute SQL querioes to get the counts etc.


Not really an option to use SQL just for this.


I'm curious why?
It seems to suggest that using SQL is somehow a big deal?

But with the SqlLite database access that ships with Python 2.5+
the database is just a normal file and you access it using
SQL commands. There is no database server or DBA involvement
etc. if that is your concern.

SqlLite is specifically designed for these kinds of small scale
ad-hoc query of complex data type of scenarios.

Or is there something else that rules it out?

Alan G. 



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-07-01 Thread Norman Khine



Alan Gauld wrote:

Norman Khine [EMAIL PROTECTED] wrote


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


Not really an option to use SQL just for this.


I'm curious why?
It seems to suggest that using SQL is somehow a big deal?


I am not sure how to implement this for now, as I have not used SqlLite.



But with the SqlLite database access that ships with Python 2.5+
the database is just a normal file and you access it using
SQL commands. There is no database server or DBA involvement
etc. if that is your concern.

SqlLite is specifically designed for these kinds of small scale
ad-hoc query of complex data type of scenarios.


I will look into this, but for now, can you advise on how to loop 
through the list and add each item found to the counter as this is the 
logic I don't understand.




Or is there something else that rules it out?

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] list objects are unhashable

2008-06-30 Thread Norman Khine


Hello,

I would like to count list items but am not 100% sure how to do it.

Here is what I have so far:

for brain in brains:
x = getattr(brain, horizontal)
y = getattr(brain, vertical)
if x and y and (x, y) in table:
table[(x, y)] += 1
table[(x, '')] += 1
table[('', y)] += 1
table[('', '')] += 1

but when I run this, I get the following error on the line:

if x and y and (x, y) in table:

TypeError: list objects are unhashable

where:

x = ['airlines-scheduled', 'airport-car-parking']


I am basically looping through files within each file, I have an entity, 
for example:


file1
topicairlines-scheduled airport-car-parking/topic

file2
topicairport-car-parking/topic

etc...

So the above code counts all occurrences of  'airport-car-parking' and 
sums it up.


All works well if, I change the code to:

for brain in brains:
x = getattr(brain, horizontal)
x = string.join(x, '' )
y = getattr(brain, vertical)
y = string.join(y, '' )
if x and y and (x, y) in table:
table[(x, y)] += 1
table[(x, '')] += 1
table[('', y)] += 1
table[('', '')] += 1

So now my list becomes a string, which is not really good for me, as 
this fails when there is more then one item.


Is there a better way to loop through this and sum up all occurrences of 
each entry ie  'airport-car-parking'


Cheers

Norman


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-06-30 Thread Cédric Lucantis
Le Monday 30 June 2008 20:55:36 Norman Khine, vous avez écrit :
 Hello,

 I would like to count list items but am not 100% sure how to do it.

 Here is what I have so far:

  for brain in brains:
  x = getattr(brain, horizontal)
  y = getattr(brain, vertical)
  if x and y and (x, y) in table:
  table[(x, y)] += 1
  table[(x, '')] += 1
  table[('', y)] += 1
  table[('', '')] += 1

 but when I run this, I get the following error on the line:

 if x and y and (x, y) in table:

 TypeError: list objects are unhashable

 where:

 x = ['airlines-scheduled', 'airport-car-parking']


lists are not hashable because hashing a mutable type would be dangerous, but 
tuples are if all their items are hashable too. Just replace x by tuple(x).

-- 
Cédric Lucantis
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor



Re: [Tutor] list objects are unhashable

2008-06-30 Thread Norman Khine

Thanks,
but where do i replace the x with tuple(x)

Norman

Cédric Lucantis wrote:

Le Monday 30 June 2008 20:55:36 Norman Khine, vous avez écrit :

Hello,

I would like to count list items but am not 100% sure how to do it.

Here is what I have so far:

 for brain in brains:
 x = getattr(brain, horizontal)
 y = getattr(brain, vertical)
 if x and y and (x, y) in table:
 table[(x, y)] += 1
 table[(x, '')] += 1
 table[('', y)] += 1
 table[('', '')] += 1

but when I run this, I get the following error on the line:

if x and y and (x, y) in table:

TypeError: list objects are unhashable

where:

x = ['airlines-scheduled', 'airport-car-parking']



lists are not hashable because hashing a mutable type would be dangerous, but 
tuples are if all their items are hashable too. Just replace x by tuple(x).



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-06-30 Thread Cédric Lucantis
Le Monday 30 June 2008 21:31:35, vous avez écrit :
 Thanks,
 but where do i replace the x with tuple(x)


Whenever x is hashed, ie used as a key in a dictionary. You said you have:

   table[(x, y)] += 1
  where:
 
  x = ['airlines-scheduled', 'airport-car-parking']

so you should rather write this (if y is a list too):

table[(tuple(x), tuple(y))] += 1

but of course you can also use tuples directly if your lists don't have to be 
modified:

x = ('airlines-scheduled', 'airport-car-parking')
y = (...)
table[(x, y)] += 1

-- 
Cédric Lucantis
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-06-30 Thread Alan Gauld


Norman Khine [EMAIL PROTECTED] wrote



but when I run this, I get the following error on the line:

if x and y and (x, y) in table:

TypeError: list objects are unhashable


Please post the entire error. The tiny bit you posted was
not overly helpful, usually the stacjk trace contains the
actual cause of the problem or a strong clue. However,
in this case...


x = ['airlines-scheduled', 'airport-car-parking']


You cannot use a list to access a dictionary because
dictionary keys must be immutable, and lists aren't.
When you use the 'in' operation on a dictionary it
basically searches the keys.

I am basically looping through files within each file, I have an 
entity, for example:


file1
topicairlines-scheduled airport-car-parking/topic

file2
topicairport-car-parking/topic

etc...

So the above code counts all occurrences of  'airport-car-parking' 
and sums it up.


All works well if, I change the code to:

for brain in brains:
x = getattr(brain, horizontal)
x = string.join(x, '' )
y = getattr(brain, vertical)
y = string.join(y, '' )
if x and y and (x, y) in table:
table[(x, y)] += 1
table[(x, '')] += 1
table[('', y)] += 1
table[('', '')] += 1

So now my list becomes a string, which is not really good for me, as 
this fails when there is more then one item.


Use a tuple instead of a list.
t = tuple(L)

You can use a tuple as an index to a dictionary.

HTH,

--
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-06-30 Thread Norman Khine

Hi,

Sorry, but this did not work.

I have done this, which returns the values I want (sort of)

for brain in brains:
x = getattr(brain, horizontal)
if isinstance(x, list):
for item in x:
x = item
else:
x
y = getattr(brain, vertical)
if isinstance(y, list):
for item in y:
y = item
else:
y
if x and y and (x, y) in table:
table[(x, y)] += 1
table[(x, '')] += 1
table[('', y)] += 1
table[('', '')] += 1


The only think is that, the totals are correct, but when there is an 
item that is in both, it is counted only once.


Cédric Lucantis wrote:

Le Monday 30 June 2008 21:31:35, vous avez écrit :

Thanks,
but where do i replace the x with tuple(x)



Whenever x is hashed, ie used as a key in a dictionary. You said you have:


 table[(x, y)] += 1
where:

x = ['airlines-scheduled', 'airport-car-parking']


so you should rather write this (if y is a list too):

table[(tuple(x), tuple(y))] += 1

but of course you can also use tuples directly if your lists don't have to be 
modified:


x = ('airlines-scheduled', 'airport-car-parking')
y = (...)
table[(x, y)] += 1


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] list objects are unhashable

2008-06-30 Thread Martin Walsh
Hi Norman,

Norman Khine wrote:
 
 for brain in brains:
 x = getattr(brain, horizontal)
 x = string.join(x, '' )
 y = getattr(brain, vertical)
 y = string.join(y, '' )
 if x and y and (x, y) in table:
 table[(x, y)] += 1
 table[(x, '')] += 1
 table[('', y)] += 1
 table[('', '')] += 1

For what it's worth, string.join has been deprecated since the addition
of the join method for str and unicode types. Other deprecated string
module functions are documented here: http://docs.python.org/lib/node42.html

If I'm not mistaken, the conventional form would be:

  x = ''.join(x)

 
 So now my list becomes a string, which is not really good for me, as
 this fails when there is more then one item.
 
 Is there a better way to loop through this and sum up all occurrences of
 each entry ie  'airport-car-parking'

Maybe, can you show us a brief excerpt of what 'table' might look like
before the loop, and what you expect it to look like after one
iteration, with data samples for both x and y?

Most likely it's just me, but I'm having trouble reconciling your code
examples with your questions. AFAICT, either you want more than just a
simple count of occurrences from your data set, or you have some
confusion regarding dictionaries (if 'table' is a dictionary, of course).

If you want a count of each unique occurrence in a list -- not sure if
it's better, but something like this might get you started (untested):

from sets import Set
x = ['airlines-scheduled', 'airport-car-parking',
 'more-than-100ml', 'do-not-bring-toothpaste',
 'airport-car-parking', 'airlines-scheduled']

entity_count = dict((item, x.count(item)) for item in Set(x))
print entity_count['airlines-scheduled']
# 2

HTH,
Marty

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor