def itershuffle(iterable, bufsize=<NUM_LIT:1000>):
iterable = iter(iterable)<EOL>buf = []<EOL>try:<EOL><INDENT>while True:<EOL><INDENT>for i in range(random.randint(<NUM_LIT:1>, bufsize - len(buf))):<EOL><INDENT>buf.append(next(iterable))<EOL><DEDENT>random.shuffle(buf)<EOL>for i in range(random.randint(<NUM_LIT:1>, bufsize)):<EOL><INDENT>if buf:<EOL><INDENT>yield buf.pop()<EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT><DEDENT>except StopIteration:<EOL><INDENT>random.shuffle(buf)<EOL>while buf:<EOL><INDENT>yield buf.pop()<EOL><DEDENT>raise StopIteration<EOL><DEDENT>
Shuffle an iterator. This works by holding `bufsize` items back
    and yielding them sometime later. Obviously, this is not unbiased –
    but should be good enough for batching. Larger bufsize means less bias.
    From https://gist.github.com/andres-erbsen/1307752

    iterable (iterable): Iterator to shuffle.
    bufsize (int): Items to hold back.
    YIELDS (iterable): The shuffled iterator.