[Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
list1
[['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
'70', '61', '34'], ['34', '58', '34', '58']]
 weight={}
 weight{list1[0]}=1
SyntaxError: invalid syntax
 weight[list1[0]]=1

Traceback (most recent call last):
  File pyshell#292, line 1, in module
weight[list1[0]]=1
TypeError: unhashable type: 'list'


I wonder how to count the occurence of the list of lists.

Thanks, ^_^
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Christian Witts

On 2011/11/17 11:59 AM, lina wrote:

list1
[['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
'70', '61', '34'], ['34', '58', '34', '58']]

weight={}
weight{list1[0]}=1

SyntaxError: invalid syntax

weight[list1[0]]=1

Traceback (most recent call last):
   File pyshell#292, line 1, inmodule
 weight[list1[0]]=1
TypeError: unhashable type: 'list'
I wonder how to count the occurence of the list of lists.

Thanks, ^_^
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


sum(1 if type(elem) == list else 0 for elem in list1) not work for you 
if all you want to do is count how many lists you have in your main list ?

--

Christian Witts
Python Developer
//
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
On Thu, Nov 17, 2011 at 6:09 PM, Christian Witts cwi...@compuscan.co.za wrote:
 On 2011/11/17 11:59 AM, lina wrote:

 list1
 [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
 '70', '61', '34'], ['34', '58', '34', '58']]

 weight={}
 weight{list1[0]}=1

 SyntaxError: invalid syntax

 weight[list1[0]]=1

 Traceback (most recent call last):
   File pyshell#292, line 1, in module
 weight[list1[0]]=1
 TypeError: unhashable type: 'list'

 I wonder how to count the occurence of the list of lists.

 Thanks, ^_^
 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor


 sum(1 if type(elem) == list else 0 for elem in list1) not work for you if
 all you want to do is count how many lists you have in your main list ?
not count how many sublists in the main list.

wanna count the occurence of the sublists,

I mean, something like

 dictionary[list1[1]]=occurence

Traceback (most recent call last):
  File pyshell#298, line 1, in module
dictionary[list1[1]]=1
TypeError: unhashable type: 'list'


 --
 dictionary[list1[1]]=1

Traceback (most recent call last):
  File pyshell#298, line 1, in module
dictionary[list1[1]]=1
TypeError: unhashable type: 'list'

 Christian Witts
 Python Developer

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Christian Witts

On 2011/11/17 12:26 PM, lina wrote:

On Thu, Nov 17, 2011 at 6:09 PM, Christian Wittscwi...@compuscan.co.za  wrote:

On 2011/11/17 11:59 AM, lina wrote:

list1
[['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
'70', '61', '34'], ['34', '58', '34', '58']]

weight={}
weight{list1[0]}=1

SyntaxError: invalid syntax

weight[list1[0]]=1

Traceback (most recent call last):
   File pyshell#292, line 1, inmodule
 weight[list1[0]]=1
TypeError: unhashable type: 'list'

I wonder how to count the occurence of the list of lists.

Thanks, ^_^
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


sum(1 if type(elem) == list else 0 for elem in list1) not work for you if
all you want to do is count how many lists you have in your main list ?

not count how many sublists in the main list.

wanna count the occurence of the sublists,

I mean, something like


dictionary[list1[1]]=occurence

Traceback (most recent call last):
   File pyshell#298, line 1, inmodule
 dictionary[list1[1]]=1
TypeError: unhashable type: 'list'

dictionary[list1[1]]=1

Traceback (most recent call last):
   File pyshell#298, line 1, inmodule
 dictionary[list1[1]]=1
TypeError: unhashable type: 'list'



For that you'll need to convert your list to a hash-able type if you 
want to use dictionaries for your store, easiest would probably to use 
the string representation for it so you could do


 list1 = [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], 
['61', '70', '61', '34'], ['34', '58', '34', '58']]

 weight = {}
 for elem in list1:
...   if elem.__repr__() in weight:
...   weight[elem.__repr__()] += 1
...   else:
...   weight[elem.__repr__()] = 1
...
 weight
{['34', '58', '34', '58']: 1, ['61', '70', '61', '34']: 1, ['61', 
'34', '61

', '34']: 1, ['61', '35', '61', '70', '61']: 1}

or

 from collections import defaultdict
 list1 = [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], 
['61', '7

0', '61', '34'], ['34', '58', '34', '58']]
 weight = defaultdict(int)
 for elem in list1:
... weight[elem.__repr__()] += 1
...
 weight
defaultdict(type 'int', {['34', '58', '34', '58']: 1, ['61', '70', 
'61', '34']: 1, ['61', '34', '61', '34']: 1, ['61', '35', '61', 
'70', '61']: 1})


Hope that helps.

--

Christian Witts
Python Developer
//
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Steven D'Aprano

lina wrote:

list1
[['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
'70', '61', '34'], ['34', '58', '34', '58']]


You have a list of lists.



weight={}
weight{list1[0]}=1

SyntaxError: invalid syntax


In Python, {} are used for dicts, and in Python 3, sets. They aren't 
used for anything else. obj{...} is illegal syntax.




weight[list1[0]]=1


Traceback (most recent call last):
  File pyshell#292, line 1, in module
weight[list1[0]]=1
TypeError: unhashable type: 'list'


You are trying to store a list as a key inside a dict. This cannot be 
done because lists (like all mutable types) can't be hashed.


If your list of lists is small, say, less than a few thousand items, it 
would be fast enough to do this:


counts = []
seen = []
for sublist in list1:
if sublist in seen:
# No need to do it again.
continue
seen.append(sublist)
counts.append( (sublist, list1.count(sublist)) )


If I run this code on your list1, I get these counts:

[(['61', '34', '61', '34'], 1), (['61', '35', '61', '70', '61'], 1), 
(['61', '70', '61', '34'], 1), (['34', '58', '34', '58'], 1)]



That is, each list is unique.

However, if you have many thousands of items, the above may be too slow. 
It is slow because of all the linear searches: sublist in seen 
searches seen for the sublist, one item at a time, and 
list1.count(sublist) searches list1 for sublist, also one item at a 
time. If there are many items, this will be slow.


To speed it up, you can do this:

(1) Keep the seen list sorted, and use binary search instead of linear 
search. See the bisect module for help.


(2) Sort list1, and write your own smarter count() function that doesn't 
have to travel along the entire list.



All that involves writing a lot of code though. Probably much faster 
would be to make a temporary copy of list1, with the inner lists 
converted to tuples:



list2 = [tuple(l) for l in list1]
counts = {}
for t in list2:
counts[t] = 1 + counts.get(t, 0)

for t, n in counts.items():
print list(t), n


--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
snip
 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor


 sum(1 if type(elem) == list else 0 for elem in list1) not work for you if
 all you want to do is count how many lists you have in your main list ?

 not count how many sublists in the main list.

 wanna count the occurence of the sublists,

 I mean, something like

 dictionary[list1[1]]=occurence

 Traceback (most recent call last):
   File pyshell#298, line 1, in module
 dictionary[list1[1]]=1
 TypeError: unhashable type: 'list'

 dictionary[list1[1]]=1

 Traceback (most recent call last):
   File pyshell#298, line 1, in module
 dictionary[list1[1]]=1
 TypeError: unhashable type: 'list'


 For that you'll need to convert your list to a hash-able type if you want to
 use dictionaries for your store, easiest would probably to use the string
 representation for it so you could do

 list1 = [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'],
 ['61', '70', '61', '34'], ['34', '58', '34', '58']]
 weight = {}
 for elem in list1:
 ...   if elem.__repr__() in weight:

This is cool.

May I ask which role the __repr__ plays here?

 ...       weight[elem.__repr__()] += 1
 ...   else:
 ...       weight[elem.__repr__()] = 1
 ...
 weight
 {['34', '58', '34', '58']: 1, ['61', '70', '61', '34']: 1, ['61', '34',
 '61
 ', '34']: 1, ['61', '35', '61', '70', '61']: 1}

 or

 from collections import defaultdict
 list1 = [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'],
 ['61', '7
 0', '61', '34'], ['34', '58', '34', '58']]
 weight = defaultdict(int)
 for elem in list1:
 ... weight[elem.__repr__()] += 1
 ...
 weight
 defaultdict(type 'int', {['34', '58', '34', '58']: 1, ['61', '70',
 '61', '34']: 1, ['61', '34', '61', '34']: 1, ['61', '35', '61', '70',
 '61']: 1})

 Hope that helps.

 --

 Christian Witts
 Python Developer

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
On Thu, Nov 17, 2011 at 8:17 PM, Steven D'Aprano st...@pearwood.info wrote:
 lina wrote:

 list1
 [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'], ['61',
 '70', '61', '34'], ['34', '58', '34', '58']]

 You have a list of lists.


 weight={}
 weight{list1[0]}=1

 SyntaxError: invalid syntax

 In Python, {} are used for dicts, and in Python 3, sets. They aren't used
 for anything else. obj{...} is illegal syntax.


 weight[list1[0]]=1

 Traceback (most recent call last):
  File pyshell#292, line 1, in module
    weight[list1[0]]=1
 TypeError: unhashable type: 'list'

 You are trying to store a list as a key inside a dict. This cannot be done
 because lists (like all mutable types) can't be hashed.

I checked online dictionary, still confused about hashed. is it equal
to mix together or mess together?

 If your list of lists is small, say, less than a few thousand items, it
 would be fast enough to do this:

 counts = []
 seen = []
 for sublist in list1:
    if sublist in seen:
        # No need to do it again.
        continue
    seen.append(sublist)
    counts.append( (sublist, list1.count(sublist)) )

Thanks, can I print the counts based on its value?


 If I run this code on your list1, I get these counts:

 [(['61', '34', '61', '34'], 1), (['61', '35', '61', '70', '61'], 1), (['61',
 '70', '61', '34'], 1), (['34', '58', '34', '58'], 1)]


 That is, each list is unique.

 However, if you have many thousands of items, the above may be too slow. It
 is slow because of all the linear searches: sublist in seen searches seen
 for the sublist, one item at a time, and list1.count(sublist) searches
 list1 for sublist, also one item at a time. If there are many items, this
 will be slow.

 To speed it up, you can do this:

 (1) Keep the seen list sorted, and use binary search instead of linear
 search. See the bisect module for help.

 (2) Sort list1, and write your own smarter count() function that doesn't
 have to travel along the entire list.


 All that involves writing a lot of code though. Probably much faster would
 be to make a temporary copy of list1, with the inner lists converted to
 tuples:


 list2 = [tuple(l) for l in list1]
 counts = {}
 for t in list2:
    counts[t] = 1 + counts.get(t, 0)

 for t, n in counts.items():
    print list(t), n


 --
 Steven
 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Steven D'Aprano

lina wrote:


May I ask which role the __repr__ plays here?
...   weight[elem.__repr__()] += 1

...   else:
...   weight[elem.__repr__()] = 1
...


You should never call elem.__repr__(), any more than you would call 
elem.__len__() or elem.__str__().


(Well, technically there *are* rare uses for calling such double 
underscore special methods directly, but this is not one of them!)


Instead, you should call repr(elem), len(elem), str(elem).

The purpose here is to convert the sublist, elem, which is unhashable, 
into something which is hashable. Strings are hashable, and so if you 
use repr() to convert it into a string, you can use it in a dictionary.


I don't see any advantage to using repr() instead of str(). Given the 
data you are working with, there is no difference:



py str([['1', '2'], ['33', '44']])
[['1', '2'], ['33', '44']]
py repr([['1', '2'], ['33', '44']])
[['1', '2'], ['33', '44']]


In my opinion, turning objects into strings unnecessarily is not good 
practice. Better to use a tuple than a string.



--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Christian Witts

On 2011/11/17 03:56 PM, lina wrote:

snip

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


sum(1 if type(elem) == list else 0 for elem in list1) not work for you if
all you want to do is count how many lists you have in your main list ?

not count how many sublists in the main list.

wanna count the occurence of the sublists,

I mean, something like

dictionary[list1[1]]=occurence

Traceback (most recent call last):
   File pyshell#298, line 1, inmodule
 dictionary[list1[1]]=1
TypeError: unhashable type: 'list'

dictionary[list1[1]]=1

Traceback (most recent call last):
   File pyshell#298, line 1, inmodule
 dictionary[list1[1]]=1
TypeError: unhashable type: 'list'


For that you'll need to convert your list to a hash-able type if you want to
use dictionaries for your store, easiest would probably to use the string
representation for it so you could do


list1 = [['61', '34', '61', '34'], ['61', '35', '61', '70', '61'],
['61', '70', '61', '34'], ['34', '58', '34', '58']]
weight = {}
for elem in list1:

...   if elem.__repr__() in weight:

This is cool.

May I ask which role the __repr__ plays here?


__repr__ is the string representation of a Python object [1] so I'm 
using it to create something that is hash-able to be used as the 
dictionary key value.


[1] http://docs.python.org/library/functions.html#repr

--

Christian Witts
Python Developer
//
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Walter Prins
Hi Lina

On 17 November 2011 14:04, lina lina.lastn...@gmail.com wrote:

  Traceback (most recent call last):
   File pyshell#292, line 1, in module
 weight[list1[0]]=1
  TypeError: unhashable type: 'list'
 
  You are trying to store a list as a key inside a dict. This cannot be
 done
  because lists (like all mutable types) can't be hashed.

 I checked online dictionary, still confused about hashed. is it equal
 to mix together or mess together?


No you need to think programming/computer science where hash/hashing
has a different meaning.  See wikipedia:
http://en.wikipedia.org/wiki/Hash_function
http://en.wikipedia.org/wiki/Hash_table

Also see the description for hashable in the Python glossary:
http://docs.python.org/glossary.html#hashable

Basically hashing is a way to convert something (often a string) into an
identifying number (not neccesarily but usually unique) in order to use
this number as a token for the original thing.  Aside, you can infer that
that because the dict code complains about hashing implies that dicts
themselves are essentially implemented as hash tables... ;)

HTH,

Walter
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
Thanks for all. Everything new to me is so amazing.

Well, still a remaining question, how to sort based on the value of the key.

Actually I googled hours ago, wanna see more ways of doing it.

Best regards,


 On 17 November 2011 14:04, lina lina.lastn...@gmail.com wrote:

  Traceback (most recent call last):
   File pyshell#292, line 1, in module
     weight[list1[0]]=1
  TypeError: unhashable type: 'list'
 
  You are trying to store a list as a key inside a dict. This cannot be
  done
  because lists (like all mutable types) can't be hashed.

 I checked online dictionary, still confused about hashed. is it equal
 to mix together or mess together?

 No you need to think programming/computer science where hash/hashing has
 a different meaning.  See wikipedia:
 http://en.wikipedia.org/wiki/Hash_function
 http://en.wikipedia.org/wiki/Hash_table

 Also see the description for hashable in the Python glossary:
 http://docs.python.org/glossary.html#hashable

 Basically hashing is a way to convert something (often a string) into an
 identifying number (not neccesarily but usually unique) in order to use this
 number as a token for the original thing.  Aside, you can infer that that
 because the dict code complains about hashing implies that dicts
 themselves are essentially implemented as hash tables... ;)

 HTH,

 Walter



 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Steven D'Aprano

lina wrote:


You are trying to store a list as a key inside a dict. This cannot be done
because lists (like all mutable types) can't be hashed.


I checked online dictionary, still confused about hashed. is it equal
to mix together or mess together?


Almost.

In ordinary English, a hash is a mixed up mess. For example, hash 
browns are fried mashed potato.


In computing, a hash got its name by analogy with mixed up. A hash is 
short for hash table.


An ordinary table might look something like this:


Position  Value
1 Fred
2 Barney
3 George
4 Betty
5 Mary
6 *unused*
7 *unused*
8 *unused*
9 *unused*


To find whether Mary is in the table, you have to start at position 1, 
and inspect each value to see whether it equals Mary:


for position 1 to 9:
if value at position == Mary: print FOUND


If there are many items, this will be slow. But here's a faster way, 
using a hash table:


Position  Value
1 *unused*
2 Barney
3 *unused*
4 Betty
5 *unused*
6 *unused*
7 Fred
8 Mary
9 George

Take the string Mary, and mix it up into a hash value between 1 and 
9. In this case, you will get 8. Look in position 8, and you will find 
Mary.


Take the string Susan and mix it up into a hash value. In this case, 
you might get 3. Since position 3 is actually unused, you know that 
Susan is not in the hash table.



All the hard work is done in the mixing of the string. This is called 
a hash function, and Python already has one:


py hash(Mary)
-1963774307
py hash(Susan)
92926151


If you change just one letter of the string, the hash can change a lot:


py hash(abcdef)
-33722981
py hash(bbcdef)
-508939398


But lists are not hashable, because they are mutable (can be changed):

py hash([1, 2, 3])
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: unhashable type: 'list'


Python dictionaries are hash tables. You could have a million items in a 
dict, and to check whether Mary is one of them with a list would 
require you to check all one million items. But with a dict, Python 
hashes the string to get a number, then reduces that number to fit 
within the range of positions in the dict, then looks immediately in the 
right spot to find Mary.




--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread lina
On Thu, Nov 17, 2011 at 10:44 PM, Steven D'Aprano st...@pearwood.info wrote:
 lina wrote:

 You are trying to store a list as a key inside a dict. This cannot be
 done
 because lists (like all mutable types) can't be hashed.

 I checked online dictionary, still confused about hashed. is it equal
 to mix together or mess together?

 Almost.

 In ordinary English, a hash is a mixed up mess. For example, hash browns
 are fried mashed potato.

 In computing, a hash got its name by analogy with mixed up. A hash is
 short for hash table.

 An ordinary table might look something like this:


 Position  Value
 1         Fred
 2         Barney
 3         George
 4         Betty
 5         Mary
 6         *unused*
 7         *unused*
 8         *unused*
 9         *unused*


 To find whether Mary is in the table, you have to start at position 1, and
 inspect each value to see whether it equals Mary:

 for position 1 to 9:
    if value at position == Mary: print FOUND


 If there are many items, this will be slow. But here's a faster way, using a
 hash table:

 Position  Value
 1         *unused*
 2         Barney
 3         *unused*
 4         Betty
 5         *unused*
 6         *unused*
 7         Fred
 8         Mary
 9         George

 Take the string Mary, and mix it up into a hash value between 1 and 9.
 In this case, you will get 8. Look in position 8, and you will find Mary.

 Take the string Susan and mix it up into a hash value. In this case, you
 might get 3. Since position 3 is actually unused, you know that Susan is
 not in the hash table.


 All the hard work is done in the mixing of the string. This is called a
 hash function, and Python already has one:

 py hash(Mary)
 -1963774307
 py hash(Susan)
 92926151


 If you change just one letter of the string, the hash can change a lot:


 py hash(abcdef)
 -33722981
 py hash(bbcdef)
 -508939398


 But lists are not hashable, because they are mutable (can be changed):

 py hash([1, 2, 3])
 Traceback (most recent call last):
  File stdin, line 1, in module
 TypeError: unhashable type: 'list'


 Python dictionaries are hash tables. You could have a million items in a
 dict, and to check whether Mary is one of them with a list would require
 you to check all one million items. But with a dict, Python hashes the
 string to get a number, then reduces that number to fit within the range of
 positions in the dict, then looks immediately in the right spot to find
 Mary.


Really appreciated for your detailed explaination.

Right now I wanna check which are not hash-able, for strings, set, and
tuple (which I don't understand).

Seems string is hash-able.

Just another quick Q:

 basket
['apple', 'pineapple', 'apple', 'pear']

 hash(basket[1])
-8771120720059735049
 hash(basket[2])
6709291584508918021

 print(id(basket))
29215848
 print(id(basket[1]))
27389096

What are those numbers means? Sorry,


 --
 Steven
 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Steven D'Aprano

lina wrote:


Right now I wanna check which are not hash-able, for strings, set, and
tuple (which I don't understand).


Mutable objects are those that can be changed in place: lists, sets, 
dicts are all mutable, because you can change them:


 mylist = [1, 2, 3]
 mylist[1] = 200
 print mylist
[1, 200, 3

Mutable objects are not hashable.


Immutable objects are those that cannot be changed in place: you have to 
create a new object. Tuples, frozensets, strings, ints, floats are all 
immutable. They are hashable.





Seems string is hash-able.

Just another quick Q:


basket

['apple', 'pineapple', 'apple', 'pear']


hash(basket[1])

-8771120720059735049

hash(basket[2])

6709291584508918021



The number doesn't mean anything. It's just a number. It gets used by 
dictionaries for fast searching, but that's all.


This might help you understand. Here is a very simple hash function that 
takes a string and mixes it up to make a number. It isn't very good, it 
is a terrible hash function, but it is simple! The Python one is better, 
but this will give you an idea of how they work:



def my_hash(string):
num = 102345  # some random number I just made up
for c in string:
num = (num*17 + ord(c)*9) % 3200
return num


Designing a good hash function is very hard.




print(id(basket))

29215848

print(id(basket[1]))

27389096



The id() of an object is just an identity number. Do you have a passport 
or driver's licence? Or a social security number? That is like your ID. 
It identifies you. Nobody else can have the same ID at the same time.


In CPython, IDs are large numbers, and they are re-usable. If you delete 
an object, another object can get the same ID later on.


In Jython and IronPython, IDs start counting at 1 and increase with 
every object created. Used IDs are never reused.


IDs aren't important. In 15 years of using Python, I don't think I have 
needed to care about the ID of an object once.



--
Steven

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Peter Otten
Steven D'Aprano wrote:

 Immutable objects are those that cannot be changed in place: you have to
 create a new object. Tuples, frozensets, strings, ints, floats are all
 immutable. They are hashable.

Tuples are special: there are hashable and unhashable tuples. To be hashable 
all items in a tuple have to be hashable:

 a = 1, 2
 hash(a)
3713081631934410656
 b = 1, []
 hash(b)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: unhashable type: 'list'

Instances of custom classes are special, too; by default they are hashable 
and mutable. That is possible without messing things up too much because 
instead of the instance's data they use its id() to calculate the hash value 
(and object equality). This is obvious in older Python versions like

Python 2.6.4 (r264:75706, Dec  7 2009, 18:43:55)
[GCC 4.4.1] on linux2
Type help, copyright, credits or license for more information.
 class A: pass
...
 a = A()
 id(a)
140312106243352
 hash(a)
140312106243352
 id(a) == hash(a)
True

but the principle also applies in 2.7 and 3.1 and above.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to understand unhashable type: 'list'

2011-11-17 Thread Alan Gauld

On 17/11/11 15:30, lina wrote:


tuple (which I don't understand).


You mean you don't understand the term 'tuple'?
Basically its just a collection of data.
You can get a
triple - 3 items,
a quadruple - 4 items,
quintiple - 5 items etc

The generic term for a collection of N items is a tuple.
triple, quadruple, etc are all specific types of tuple.

It's a math thing...

In python a tuple is just lie a list except you can't
change it - ie. it is immutable. This makes it perfect
for using as a key in a dictionary when you'd like to
use a list...

As an aside some folks like to distinguish between tuples and lists by 
suggesting that tuples can hold collections of different types of data:

t = (1,'two', 3.0) whereas lists should only hold items of the same type.
L = [1,2,3]
But that's a semantic nicety, Python doesn't make any such distinction.
And for dictionary keys (1,2,3) is the only way to do it...

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor