This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: random.choice([]) should return more intelligible exception
Type: Stage:
Components: Library (Lib) Versions: Python 2.4
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: hoffman, rhettinger, terry.reedy
Priority: low Keywords:

Created on 2004-06-01 12:39 by hoffman, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg20945 - (view) Author: Michael Hoffman (hoffman) Date: 2004-06-01 12:39
Python 2.3.3 (#1, Mar 31 2004, 11:17:07)
[GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)] on linux2
Type "help", "copyright", "credits" or "license" for
more information.
>>> import random
>>> random.choice([])
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.3/random.py", line 231, in choice
    return seq[int(self.random() * len(seq))]
IndexError: list index out of range

This is simple enough here, but it's harder when it's
at the bottom of a traceback.

I suggest something like ValueError: sequence must not
be empty.
msg20946 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-06-05 05:39
Logged In: YES 
user_id=80475

-0

While a ValueError would be appropriate, the status quo
doesn't bug me much and changing it could break code if
someone is currently trapping the IndexError.  

msg20947 - (view) Author: Michael Hoffman (hoffman) Date: 2004-06-05 06:19
Logged In: YES 
user_id=987664

I thought of that after I submitted. :-)

Might it be better to raise an IndexError with a message 
similar to "sequence must not be empty" instead? It would 
just make debugging that much easier.
msg20948 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-06-05 06:41
Logged In: YES 
user_id=80475

That's better, but I'm still -0.   This function is apt to
be called inside a loop, so it would be a bummer to slow
down everyone's code just to rewrite the error message.

For better or worse, it is the nature of Python tracebacks
to raise RoadWeavingErrors when a DontDrinkAndDriveWarning
would be more to the point.

I recommend closing this, but if you really think it's an
essential life saver, then assign to Tim and see if you can
persuade him.
msg20949 - (view) Author: Michael Hoffman (hoffman) Date: 2004-06-05 09:24
Logged In: YES 
user_id=987664

You have a point. What about rewriting the line to read: 
return seq[int(self.random() * len(seq))] # raises IndexError if 
seq is empty

The comment would be a good hint.
msg20950 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2004-06-05 14:54
Logged In: YES 
user_id=80475

Okay.  Fixed.  See Lib/random.py 1.61.
msg20951 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2004-06-05 15:51
Logged In: YES 
user_id=593130

More succinctly:
# empty seq raises IndexError
Commenting source code for traceback clarity has been 
suggested before as a way to enhance without breaking.  
Works for me

For making repeated choices, however, a generator would be 
faster for n much larger than 0.  Something like

def chooser(count, seq):
  if type(count) not in (int, long) or count < 0:
    raise ValueError('%s is not a count' % count)
  try:
    seqlen = len(seq)
    if not seqlen: raise ValueError('Cannot choose from 
nothing')
  except TypeError:
    raise ValueError('Seq arg must have length')
  while count:
    yield seq[int(self.random() * seqlen)]
    count -= 1
History
Date User Action Args
2022-04-11 14:56:04adminsetgithub: 40318
2004-06-01 12:39:19hoffmancreate