xrange not hashable - why not?
Isaac To
kkto at csis.hku.hk
Sun Jan 25 21:14:48 EST 2004
>>>>> "Andrew" == Andrew MacIntyre <andymac at bullseye.apana.org.au> writes:
>> why is an xrange object not hashable?
Andrew> xrange() returns an iterator. iterators seem universally
Andrew> unhashable, probably because they can't be deemed "concrete",
Andrew> though I can't find anything in the 2.3.3 docs about this -
Andrew> perhaps the relevant PEPs might.
xrange's are hashable in Python 2.3.
>> I was trying to do something like:
>>
>> comments = { xrange(0, 4): "Few", xrange(4, 10): "Several",
>> xrange(10, 100): "A lot", xrange(100, sys.maxint): "Can't count
>> them"} for (k, v) in comments.items(): if n in k: commentaar = v
>> break
Andrew> Even if it worked, there's a nasty performance trap in the
Andrew> sys.maxint case: if the sys.maxint case is the first returned by
Andrew> the items() method call and n < 100, the "in" will evaluate the
Andrew> sys.maxint xrange iterator.
I used to think that the code won't work at all. I think xrange works like
generators. If that is the case, the state stored within the xrange in the
dict will cause the whole thing to fail if the same range is used the second
time. E.g.,
>>> def yrange(x,y):
... ret = x
... while ret < y:
... yield ret
... ret += 1
...
>>> for a in yrange(1,5):
... print a
...
1
2
3
4
>>> comments = {
... yrange(0, 4): "Few",
... yrange(4,10): "Several",
... yrange(10,100): "A lot",
... yrange(100, sys.maxint): "Can't count them"}
>>> for (k,v) in comments.items():
... if 1 in k:
... print v
... break
...
Few
>>> for (k,v) in comments.items():
... if 1 in k:
... print v
... break
... (type interrupt here after waiting for some time)
Traceback (most recent call last):
File "<stdin>", line 2, in ?
File "<stdin>", line 5, in yrange
KeyboardInterrupt
But for xrange this is not the case:
>>> comments = {
... xrange(0, 4): "Few",
... xrange(4, 10): "Several",
... xrange(10, 100): "A lot",
... xrange(100, sys.maxint): "Can't count them"}
>>> for (k,v) in comments.items():
... if 1 in k:
... print v
... break
...
Few
>>> for (k,v) in comments.items():
... if 1 in k:
... print v
... break
...
Few
So xrange is not just an iterator. On the other hand, things like 1000000
in xrange(1,sys.maxint) really needs a long time to compute. That makes me
wonder how xrange's are actually implemented.
Regards,
Isaac.
More information about the Python-list
mailing list