Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #40727 > unrolled thread

iterating over a list as if it were a circular list

Started bySven <svenito@gmail.com>
First post2013-03-07 09:27 +0000
Last post2013-03-08 17:59 +0000
Articles 4 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  iterating over a list as if it were a circular list Sven <svenito@gmail.com> - 2013-03-07 09:27 +0000
    Re: iterating over a list as if it were a circular list Alexander Blinne <news@blinne.net> - 2013-03-08 00:49 +0100
      Re: iterating over a list as if it were a circular list Alexander Blinne <news@blinne.net> - 2013-03-08 00:50 +0100
    Re: iterating over a list as if it were a circular list Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-03-08 17:59 +0000

#40727 — iterating over a list as if it were a circular list

FromSven <svenito@gmail.com>
Date2013-03-07 09:27 +0000
Subjectiterating over a list as if it were a circular list
Message-ID<mailman.2994.1362648463.2939.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

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

[toc] | [next] | [standalone]


#40833

FromAlexander Blinne <news@blinne.net>
Date2013-03-08 00:49 +0100
Message-ID<51392771$0$6583$9b4e6d93@newsspool3.arcor-online.net>
In reply to#40727
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

[toc] | [prev] | [next] | [standalone]


#40834

FromAlexander Blinne <news@blinne.net>
Date2013-03-08 00:50 +0100
Message-ID<513927c1$0$6583$9b4e6d93@newsspool3.arcor-online.net>
In reply to#40833
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

[toc] | [prev] | [next] | [standalone]


#40880

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-03-08 17:59 +0000
Message-ID<513a270d$0$30001$c3e8da3$5496439d@news.astraweb.com>
In reply to#40727
On Thu, 07 Mar 2013 09:27:42 +0000, 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web