iterating over a list as if it were a circular list

2013-03-07 Thread Sven
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

2013-03-07 Thread Sven
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

2013-03-07 Thread Chris Angelico
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

2013-03-07 Thread Chris Rebert
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

2013-03-07 Thread Sven
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

2013-03-07 Thread Chris Rebert
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

2013-03-07 Thread Roy Smith
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

2013-03-07 Thread Alexander Blinne
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

2013-03-07 Thread Alexander Blinne
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

2013-03-08 Thread Steven D'Aprano
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