iterating over a list as if it were a circular list

Discussion in 'Python' started by Sven, Mar 7, 2013.

  1. Sven

    Sven Guest

    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 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
    Sven, Mar 7, 2013
    #1
    1. Advertising

  2. 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 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
    Alexander Blinne, Mar 7, 2013
    #2
    1. Advertising

  3. Alexander Blinne, Mar 7, 2013
    #3
  4. 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
    Steven D'Aprano, Mar 8, 2013
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sven
    Replies:
    1
    Views:
    137
    Roy Smith
    Mar 7, 2013
  2. Chris Angelico
    Replies:
    0
    Views:
    111
    Chris Angelico
    Mar 7, 2013
  3. Chris Rebert
    Replies:
    0
    Views:
    110
    Chris Rebert
    Mar 7, 2013
  4. Sven
    Replies:
    0
    Views:
    102
  5. Chris Rebert
    Replies:
    0
    Views:
    115
    Chris Rebert
    Mar 7, 2013
Loading...

Share This Page