Random and Itertools
<p>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:</p>

<pre><code>import itertools
import random

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

    print f
</code></pre>

<p>However this produces the following error:</p>

<pre><code>Traceback (most recent call last):
  File "&lt;pyshell#12&gt;", line 1, in &lt;module&gt;
    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()
</code></pre>

<p>Can anyone advise the amendments needed to make this function as intended?</p>

<p>A quick fix would be as follows:</p>

<pre><code>for f in random.sample(list(itertools.chain(range(30, 54), range(1, 24))), 48):
</code></pre>

<p>The problem with your code is that to sample from some iterable randomly, you need to know its length first, but <code>itertools.chain</code> is an iterable that provides only the <code>__iter__</code> method and no <code>__len__</code>. </p>

<p>Basically, to do <code>random.choice</code> or <code>random.sample</code> or anything that involves <em>choosing</em> elements at random, you'll need a sequence or a set, which means that sequence should be <em>finite</em>. Iterables that don't provide the <code>__len__</code> method are considered infinite as you'll never know how many elements will be produced until the iterable's exhausted, if at all. </p>

python random itertools sample