473,396 Members | 2,055 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

xrange not hashable - why not?

Hi,

why is an xrange object not hashable?
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

Because:
- I found it easier to extend than:
if 0 <= n < 4: return "few"
elif ... # etc
- And better readable than:
if k[0] <= n < k[1]: # using tuples
- And much more memory efficient than tuple(...) (especially the
last one ;-)

It would not be difficult to let xrange have a hash:

hash((self.start, self.step, self.stop))

would be sufficient, I think.

Hmm, start, step and stop appear to have disappeared in Python 2.3...
certainly makes it somewhat more difficult. I shouldn't even to containment
testing according to PEP 260, and Python 2.3.3 should warn me not to
do... it doesn't, however.

So, should I use one of the alternatives after all? Or does someone have
something better to offer?

yours,
Gerrit.

Jul 18 '05 #1
6 1337

"Gerrit Holl" <ge****@nl.linux.org> wrote in message
news:ma**************************************@pyth on.org...
Hi,

why is an xrange object not hashable?

I don't know the answer for this.

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


There's a bit of an efficiency issue with using 'n in k' for something like
xrange(100, sys.maxint),
since you have to walk through the items in that range to see if n is in
there, and that's a large range.
Perhaps this would help:

class bounds:
def __init__(self, start, stop, step=1):
self.start = start
self.stop = stop
self.step = step
def is_step(self, other):
q, r = divmod(other-self.start, self.step)
return r == 0
def __contains__(self, other):
return self.start <= other < self.stop and self.is_step(other)
def __hash__(self):
return id(self)
def __repr__(self):
return "bounds(start=%s, stop=%s, step=%s)"%\
(self.start, self.stop, self.step)

import sys
import random

comments = {
bounds(0, 4): "Few",
bounds(4, 10): "Several",
bounds(10, 100): "A lot",
bounds(100, sys.maxint): "Can't count them"}

n = random.randint(0, sys.maxint)
print n

for k, v in comments.iteritems():
print k
if n in k:
print v
break
else:
print n, "out of bounds"

HTH,
Sean
Jul 18 '05 #2

"Sean Ross" <sr***@connectmail.carleton.ca> wrote in message
news:FS****************@news20.bellglobal.com...
There's a bit of an efficiency issue with using 'n in k' for something like xrange(100, sys.maxint),
since you have to walk through the items in that range to see if n is in
there, and that's a large range.


Hmm, I don't think what I said there is correct, please disregard.

Sorry for any confusion,
Sean
Jul 18 '05 #3
Sean Ross wrote:
xrange(100, sys.maxint),
since you have to walk through the items in that range to see if n is in
there, and that's a large range.

Hmm, I don't think what I said there is correct, please disregard.

I think you're right though:

90000000 in xrange(1,sys.maxint) takes a long time to complete....

--Irmen
Jul 18 '05 #4
Gerrit Holl wrote:
why is an xrange object not hashable?


Because they don't have a notion of equality
beyond identity.

Regards,
Martin

Jul 18 '05 #5
Gerrit Holl wrote:
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
[...]
So, should I use one of the alternatives after all? Or does someone have
something better to offer?


I think you want bisect():

import bisect

ranges = [
(0, "Few"),
(4, "Several"),
(10, "A lot"),
(100, "Can't count them")
]

def makelookup(r):
bounds = [i[0] for i in r][1:]
names = [i[1] for i in r]
def find(value):
return names[bisect.bisect(bounds, value)]
return find

lookup = makelookup(ranges)

# use it
last = ""
for i in range(-100, 1000):
if last != lookup(i):
last = lookup(i)
print i, last

Note that names needs one more entry than bounds. I "fixed" that by
discarding the first bounds item.

Peter
Jul 18 '05 #6
> why is an xrange object not hashable?
I was trying to do something like:
Could be a hold-over from xrange trying to have all of the features of a
list returned by range; lists are unhashable because they are mutable.
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 It would not be difficult to let xrange have a hash:

hash((self.start, self.step, self.stop))
I don't believe anyone ever said it was. *wink*

Hmm, start, step and stop appear to have disappeared in Python 2.3...
I don't know about that:
Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
help(xrange)

Help on class xrange in module __builtin__:

class xrange(object)
| xrange([start,] stop[, step]) -> xrange object

So, should I use one of the alternatives after all? Or does someone have
something better to offer?


Honestly it is one of those things that are easily remedied by a
custom-built class. Like the below:

class HashableXRange:
def __init__(self, s1, s2=None, s3=None):
if s2 is None:
s1, s2, s3 = 0, s1, 1
elif s3 is None:
s3 = 1
self.start = s1
self.stop = s2
self.step = s3
def __hash__(self):
return hash((self.start, self.stop, self.step))
def __cmp__(self, other):
if isinstance(other, self.__class__):
return cmp(self.start, other.start) or\
cmp(self.stop, other.stop) or\
-cmp(self.step, other.step)
return cmp(self.start, other)
def __iter__(self):
return iter(xrange(self.start, self.stop, self.step))
def __contains__(self, object):
if self.start <= object < self.stop:
if (object-self.start) % self.step == 0:
return 1
return 0

I included the __cmp__ function in order to give it a richer set of
behavior. One thing to note about hashes is that they are not required
to be unique. As such, the hashing algorithm is not the absolute best
algorithm ever. It is pretty good, but it is not guaranteed that
hash((a,b,c)) != hash((d,e,f)) for different sets of three objects.
Better to be safe than sorry.

I would have subclassed xrange, but Python 2.3 doesn't like that.
Apparently there is no subclassing for xranges.

- Josiah
Jul 18 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Christian Neumann | last post by:
Hello, i have a problem with the built-in function xrange(). Could you by any chance be able to help? I use Python 2.3.4 (final) and i think there is a bug in the built-in
11
by: Leif K-Brooks | last post by:
I was just playing around, and noticed that modules seem to be hashable. Can anyone explain that, especially given the fact that they're mutable? Python 2.3.3 (#1, May 7 2004, 10:31:40) on...
29
by: Steve R. Hastings | last post by:
When you compile the expression for i in range(1000): pass does Python make an iterator for range(), and then generate the values on the fly? Or does Python actually allocate the list and...
1
by: Simon Pickles | last post by:
Hi, The term 'hashable'. Am I right in thinking it means it can be indexed? like a string or a dict? Thanks Si
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.