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. 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
"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
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
Gerrit Holl wrote: why is an xrange object not hashable?
Because they don't have a notion of equality
beyond identity.
Regards,
Martin
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
> 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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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
|
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...
|
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...
|
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
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
|
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,...
|
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...
|
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,...
| |