Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random and Itertools

I have some sample code that iterates through two different ranges of numbers successfully, but I want to add functionality to it so that it moves through the chained ranges randomly like so:

import itertools
import random

for f in random.sample(itertools.chain(range(30, 54), range(1, 24)), 48):

    print f

However this produces the following error:

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    for f in random.sample(itertools.chain(range(30, 54), range(1, 24)), 48):
  File "G:\Python27\lib\random.py", line 321, in sample
    n = len(population)
TypeError: object of type 'itertools.chain' has no len()

Can anyone advise the amendments needed to make this function as intended?

like image 535
gdogg371 Avatar asked Sep 20 '26 03:09

gdogg371


1 Answers

As the random.sample documentation states,

Returns a k length list of unique elements chosen from the population sequence or set

It requires a sequence or a set so that it can sample from the entire population, but itertools.chain returns an iterator which could even be infinite. So sample cannot determine the actual size of the population. That is why you are getting this error.

To fix this, you can simply create a list or a tuple and pass it to sample, like this

for f in random.sample(list(itertools.chain(range(30, 54), range(1, 24))), 48)

Note: The other problem in your code is that, the sampling quantity cannot be bigger than the actual population.

>>> len(range(30, 54))
24
>>> len(range(1, 24))
23

So the population size is 47 and you are sampling 48 elements.

like image 137
thefourtheye Avatar answered Sep 22 '26 17:09

thefourtheye