[ python-Bugs-1551113 ] random.choice(setinstance) fails

SourceForge.net noreply at sourceforge.net
Sat Sep 2 21:37:46 CEST 2006


Bugs item #1551113, was opened at 2006-09-02 14:27
Message generated for change (Comment added) made by tim_one
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1551113&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Alan (aisaac0)
Assigned to: Raymond Hettinger (rhettinger)
Summary: random.choice(setinstance) fails

Initial Comment:
It seems perverse that random.choice cannot pick from 
a set.
(Maybe it is also perverse that it cannot pick a key 
from a dict.)
The current definition is

def choice(self, seq):
    """Choose a random element from a non-empty 
sequence."""
    return seq[int(self.random() * len(seq))]  # 
raises IndexError if seq is empty

How about something along the lines of:

def choice(self, seq):
    """Choose a random element from a non-empty 
sequence."""
    idx = int(self.random() * len(seq))
    try:
        result = seq[idx]  # raises IndexError if seq 
is empty
    except TypeError:
        result = list(seq)[idx]
    return result
 


----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2006-09-02 15:37

Message:
Logged In: YES 
user_id=31435

This is certainly a feature request rather than a bug (the
code is working as documented (a set is not a sequence) and
as designed).

Change it to a feature request, and it will probably just
sit there for years ;-)  The unwritten promise is that
choice(s) on a sequence of length N will take O(1) time and
O(1) space.  There is no known way to do this given the
current implementations of dicts and sets better than O(N)
time and O(1) space (and even that poor behavior is tricky
to achieve -- the way suggested by the OP requires O(N) time
and O(N) space).

Rather than give users surprisingly atrocious performance
for one type of argument, leaving it out of choice()
emphasizes reality:  if you want efficient random selection
from a set, you /need/ to use a fancier data structure than
a Python set.  OTOH, if you don't care about efficiency,
it's hardly a burden to write random.choice(list(myset))
instead.  Then at least the atrociousness of your algorithm
design is obvious to readers of the code <0.5 wink>.

----------------------------------------------------------------------

Comment By: Georg Brandl (gbrandl)
Date: 2006-09-02 14:33

Message:
Logged In: YES 
user_id=849994

To Raymond: Wasn't there a discussion about random.choice()
some time ago?

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1551113&group_id=5470


More information about the Python-bugs-list mailing list