iterating over a list as if it were a circular list
I was wondering what the best approach for the following might be. Say you have a list P of points and another list N of other items. You can always assume that len(N) <= len(P) Now I would like to iterate over P and place one N at each point. However if you run out of N I'd like to restart from N[0] and carry on until all the points have been populated. So far I've got for point in points: -- ./Sven -- http://mail.python.org/mailman/listinfo/python-list
iterating over a list as if it were a circular list
Stupid keyboard shortcuts, sent it too early. Apologies I was wondering what the best approach for the following might be. Say you have a list P of points and another list N of other items. You can always assume that len(N) <= len(P) Now I would like to iterate over P and place one N at each point. However if you run out of N I'd like to restart from N[0] and carry on until all the points have been populated. So far I've got (pseudo code) i = 0 for point in points: put N[i] at point if i > len(N): i = 0 is this the most pythonic way to accomplish this? Additionally, what if I wanted to pull a random element from N, but I want to ensure all elements from N have been used before starting to pick already chosen random elements again. So far I thought of duplicating the list and removing the randomly chosen elements from the list, and when it's empty, re-copying it. But that seems a little "wrong" if you know what I mean. -- ./Sven -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
On Thu, Mar 7, 2013 at 8:23 PM, Sven wrote: > Now I would like to iterate over P and place one N at each point. However if > you run out of N I'd like to restart from N[0] and carry on until all the > points have been populated. Check out itertools.cycle, it should do what you want. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
On Mar 7, 2013 1:24 AM, "Sven" wrote: > > I was wondering what the best approach for the following might be. > > Say you have a list P of points and another list N of other items. You can always assume that > > len(N) <= len(P) > > Now I would like to iterate over P and place one N at each point. However if you run out of N I'd like to restart from N[0] and carry on until all the points have been populated. Untested due to the late hour: import itertools for p, n in itertools.izip(P, itertools.cycle(N)): # do whatever -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
On 7 March 2013 09:31, Chris Rebert wrote: > On Mar 7, 2013 1:24 AM, "Sven" wrote: > > > > I was wondering what the best approach for the following might be. > > > > Say you have a list P of points and another list N of other items. You > can always assume that > > > > len(N) <= len(P) > > > > Now I would like to iterate over P and place one N at each point. > However if you run out of N I'd like to restart from N[0] and carry on > until all the points have been populated. > > Untested due to the late hour: > > import itertools > > for p, n in itertools.izip(P, itertools.cycle(N)): > # do whatever > I knew there was a more sensible way to do it. Thanks. -- ./Sven -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
On Mar 7, 2013 1:29 AM, "Sven" wrote: > > Stupid keyboard shortcuts, sent it too early. Apologies > > > I was wondering what the best approach for the following might be. > > Say you have a list P of points and another list N of other items. You can always assume that > > len(N) <= len(P) > > Now I would like to iterate over P and place one N at each point. However if you run out of N I'd like to restart from N[0] and carry on until all the points have been populated. > Additionally, what if I wanted to pull a random element from N, but I want to ensure all elements from N have been used before starting to pick already chosen random elements again. > So far I thought of duplicating the list and removing the randomly chosen elements from the list, and when it's empty, re-copying it. But that seems a little "wrong" if you know what I mean. Just iterate over the list in order, and random.shuffle() the list each time you reach the end of it. -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
In article , Sven wrote: > I was wondering what the best approach for the following might be. > > Say you have a list P of points and another list N of other items. You can > always assume that > > len(N) <= len(P) > > Now I would like to iterate over P and place one N at each point. However > if you run out of N I'd like to restart from N[0] and carry on until all > the points have been populated. > So far I've got > > for point in points: I'm not completely following what you're trying to do, but I think what you're looking for is some combination of zip() and itertools.cycle(). pairs = zip(P, cycle(N)) -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
Am 07.03.2013 10:27, schrieb Sven: > Now I would like to iterate over P and place one N at each point. > However if you run out of N I'd like to restart from N[0] and carry on > until all the points have been populated. > So far I've got (pseudo code) > > i = 0 > for point in points: > put N[i] at point > if i > len(N): > i = 0 > > is this the most pythonic way to accomplish this? Sounds like http://docs.python.org/3/library/itertools.html#itertools.repeat to me. > Additionally, what if I wanted to pull a random element from N, but I > want to ensure all elements from N have been used before starting to > pick already chosen random elements again. > So far I thought of duplicating the list and removing the randomly > chosen elements from the list, and when it's empty, re-copying it. But > that seems a little "wrong" if you know what I mean. This can be done with http://docs.python.org/3/library/random.html#random.shuffle untested: import random def repeated_random_permutation(iterable): pool = list(iterable) while True: random.shuffle(pool) yield from pool Greetings -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
Am 08.03.2013 00:49, schrieb Alexander Blinne: > http://docs.python.org/3/library/itertools.html#itertools.repeat obviously I was aiming for http://docs.python.org/2/library/itertools.html#itertools.cycle here Greetings -- http://mail.python.org/mailman/listinfo/python-list
Re: iterating over a list as if it were a circular list
On Thu, 07 Mar 2013 09:27:42 +, Sven wrote: > Additionally, what if I wanted to pull a random element from N, but I > want to ensure all elements from N have been used before starting to > pick already chosen random elements again. So far I thought of > duplicating the list and removing the randomly chosen elements from the > list, and when it's empty, re-copying it. But that seems a little > "wrong" if you know what I mean. An infinite generator is probably the best solution: import random def sample_without_replacement(alist): blist = alist[:] # Copy the list. while True: random.shuffle(blist) for value in blist: yield value Notice that I make a copy of the list before shuffling. That avoids side- effects where calling sample_without_replacement on a list modifies it. To use it, you do something like this: it = sample_without_replacement([1, 2, 3, 4, 5, 6]) next(it) => prints a random value next(it) => and a second random value To grab twenty random values all at once, you can either do this: it = sample_without_replacement([1, 2, 3, 4, 5, 6]) values = [next(it) for i in range(20)] or this: import itertools it = sample_without_replacement([1, 2, 3, 4, 5, 6]) values = itertools.islice(it, 20) -- Steven -- http://mail.python.org/mailman/listinfo/python-list