3
votes

I have a simple generator to give me permutations of a set of coordinates. I wish to save each new permutation to an element in an array using the code below:

import random
def poss_comb(coord):
    spin=random.shuffle
    if spin:
        spin(coord)
        yield (coord)
...

a=[]
for n in xrange(0,10):
    for item in poss_comb(coord):
        print item
        a.append(item)

However when printing the results printing item gives me what I want :

['0 1', '', '1 2', '1 3']
['0 1', '', '1 2', '1 3']
['1 2', '0 1', '1 3', '']
['0 1', '1 2', '', '1 3']
['1 3', '', '1 2', '0 1']
['1 3', '1 2', '0 1', '']
['0 1', '', '1 3', '1 2']
['1 2', '0 1', '', '1 3']
['1 2', '1 3', '', '0 1']
['', '1 2', '1 3', '0 1']

whereas printing list a provides an array where each element is a copy of the last permutation.

What would be a better way to do this?

1
Does your function yield the global coord or the local link? - Martijn Pieters♦
They are the same, I changed link to coord when posting for simplicity. (corrected now) - user2589273
What exactly is a coord? It's not defined anywhere. - martineau
You're simple generator poss_comb() only yields one value. - martineau
It's worth noting that there's a much easier way to append each yielded value from a generator to a list: a = list(poss_comb(coord)) (or a.extend(poss_comb(coord)) if you want to append them to an existing list instead of a new one). - abarnert

1 Answers

3
votes

Your generator does not yield new lists, it yields the same list over and over again. When you append that yielded reference to a you only get to see the same original list, in it's most recently shuffled form, over and over again.

Yield a copy instead:

def poss_comb(coord):
    coord = coord[:]  # use a local copy of the list
    random.shuffle(coord)
    yield coord

or create a random sort instead of using inplace shuffling with the sorted() function:

def poss_comb(coord):
    yield sorted(coord, key=lambda k: random.random())