I have a function that generates numbers from -180 to 180:
all_angles = list(range(-180,180))
random.shuffle(all_angles)
next_angle = iter(all_angles)
The issue is that it stops generating after 360 (which makes sense since it's from -180 to 180):
n_list = []
for i in range(1000):
n_list.append(next(next_angle))
print(len(n_list))
>>> 360 # currently it only prints 360
How can I reset it and shuffle it once it goes over all of the 360 values? So the above for loop
will generate 360 shuffled numbers, reset after it goes over all the 360 values (each appearing only once), and generate another set of 360 values, and so on.
Generator endlessly shuffling and yielding:
def endless_shuffling(iterable):
values = list(iterable)
while True:
random.shuffle(values)
yield from values
Instead of your iter(all_angles)
, use endless_shuffling(all_angles)
(and remove your own other shuffling).
One way to then get your list:
random_angles = endless_shuffling(range(-180, 180))
n_list = list(islice(random_angles, 1000))
If you give it an empty iterable and ask it for a value, it'll "hang", so either don't do that or guard against that case (e.g., with an extra if values:
or with while values:
).
I also tried a faster way to iterate than sending every value through a generator, but the shuffling dominates so it doesn't make a big difference:
with shuffling:
448.3 ms endless_shuffling1
426.7 ms endless_shuffling2
without shuffling:
26.4 ms endless_shuffling1
5.1 ms endless_shuffling2
Full code (Try it online!):
from random import shuffle
from itertools import chain, islice
from timeit import default_timer as time
def endless_shuffling1(iterable):
values = list(iterable)
while True:
shuffle(values)
yield from values
def endless_shuffling2(iterable):
values = list(iterable)
return chain.from_iterable(iter(
lambda: shuffle(values) or values,
[]
))
funcs = endless_shuffling1, endless_shuffling2
for f in funcs:
print(*islice(f('abc'), 21))
for i in range(6):
for f in funcs:
t0 = time()
next(islice(f(range(-180,180)), 999999, 1000000))
print('%5.1f ms ' % ((time() - t0) * 1e3), f.__name__)
print()
if i == 2:
print('without shuffling:\n')
def shuffle(x):
pass