More pythonic way to change an element of a tuple?
Manuel M. Garcia
mgarcia at cole-switches.com
Wed Nov 27 19:29:40 EST 2002
On Wed, 27 Nov 2002 09:58:44 -0800, in comp.lang.python you wrote:
(edit)
>I frequently have to change a single element of a tuple, and I wind up
>doing something like this:
Not recommended to have something that is mutable to give a hash
value. The internal implementation of the dictionary gets confused if
a key changes.
class list_with_hash(list):
def __hash__(self):
return hash(tuple(self))
dict0 = {}
dict1 = {}
for i in range(10):
dict0[list_with_hash([i])] = i
dict1[list_with_hash([i])] = 9-i
for k in dict1.keys():
k[0] = 9 - k[0]
print 'dict0 = %r' % (dict0)
print 'dict1 = %r' % (dict1)
for k in dict0.keys():
try:
v = dict0[k]
except KeyError:
print 'could not find key %r in dict0' % (k)
else:
print 'dict0[%r] = %r' % (k,v)
for k in dict1.keys():
try:
v = dict1[k]
except KeyError:
print 'could not find key %r in dict1' % (k)
else:
print 'dict1[%r] = %r' % (k,v)
The dictionaries 'dict0' and 'dict1' print out the same, but most of
they keys in 'dict1' just cannot be found at all.
If you change the 'list_with_hash' class to give the same hash for all
elements like this:
class list_with_hash(list):
def __hash__(self):
return 0
you will no longer have the problem of the dictionary not able to find
its own keys. But now the performance of the dictionary will be
lousy:
import time
class list_with_hash0(list):
def __hash__(self):
return hash(tuple(self))
class list_with_hash1(list):
def __hash__(self):
return 0
t1 = time.clock()
dict0 = {}
for i in range(5000):
dict0[list_with_hash0([i])] = i
for i in range(5000):
x = dict0[list_with_hash0([i])]
t2 = time.clock()
print 'time for list_with_hash0: %.3f' % (t2-t1)
t1 = time.clock()
dict1 = {}
for i in range(5000):
dict1[list_with_hash1([i])] = i
for i in range(5000):
x = dict1[list_with_hash1([i])]
t2 = time.clock()
print 'time for list_with_hash1: %.3f' % (t2-t1)
Manuel
More information about the Python-list
mailing list