Repository navigation
random.sample raises "IndexError: pop from empty list" when both "population" and "counts" are empty #130285
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Feb 18, 2025 Neither of these cases was tested or intended behavior, so it would be reasonable to fix them both. I'll work on a PR soonish. Thanks for the report.
Because of the possibility of breaking code, I'm -0 on backporting the edit.
Reacted by Stan UlbrychSomewhat related is the situation when
k=0and allcountsare zero:>>> random.sample('abc', k=0, counts=[0,0,0]) Traceback (most recent call last): File "<python-input-1>", line 1, in <module> random.sample('abc', k=0, counts=[0,0,0]) ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/path/to/lib/python3.14/random.py", line 428, in sample raise ValueError('Total of counts must be greater than zero') ValueError: Total of counts must be greater than zero
According to the docs:
Repeated elements can be specified one at a time or with the optional keyword-only counts parameter. For example,
sample(['red', 'blue'], counts=[4, 2], k=5)is equivalent tosample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5).So, extrapolating this to zero counts, this would be
random.sample('abc', k=0, counts=[0,0,0])is equivalent torandom.sample([], k=0)which, however, returns[].I propose we do
Line 421 in 8207454
cum_counts = list(_accumulate(counts)) if not cum_counts: if k == 0: return [] else: raise ValueError("Sample larger than population or is negative")Line 422 in 8207454
if len(cum_counts) != n:
And add tests, what do you think @rhettinger ? I see you are planning to do thisWhat about (random.py#L424)
total = cum_counts.pop() if cum_counts else 0 if not isinstance(total, int): raise TypeError('Counts must be integers') if total < 0: raise ValueError('Total of counts must be non-negative')
That would also address the
random.sample('abc', k=0, counts=[0,0,0]) == random.sample([], k=0)case.If
total == 0 and k > 0this also wouldn't change the type of exception as it would becomeValueError("Sample larger than population or is negative")instead.- added a commit that references this issue
on Feb 19, 2025 - addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Feb 21, 2025 - added a commit that references this issue
on Feb 21, 2025
Bug report
Bug description:
I just encountered the situation where I used
random.samplebut both thepopulationandcountsarguments were empty (my algorithm had nothing left to choose from). So, basically this situation:Instead of the
IndexError, I expected aValueError, similar to the following situations:The docs mention that
In addition, I would expect the following to work:
similar to how it works when
countsis not specified:Not sure though what CPython's backwards-compatibility policy has to say here, since changing the exception type – or, in the second case, removing the exception altogether – might actually break someone's code...
Tested with:
CPython versions tested on:
3.14
Operating systems tested on:
Linux
Linked PRs