1

The variable is changing and prints different value and it saves another If i run this code

def swap(string,x,y):
  string[y], string[x] = string[x], string[y]

def permutations(string ,i=0):
    if i == len(string):
        yield string

    for x in range(i, len(string)):
        perm = string
        swap(perm,x,i)
        yield from permutations(perm, i+1)
        swap(perm,i,x)

result = []
test = permutations(['a','b','c'])
for x in test:
    print(x)
    result.append(x)

print(result)

It prints this and i dont know why:

['a', 'b', 'c']
['a', 'c', 'b']
['b', 'a', 'c']
['b', 'c', 'a']
['c', 'b', 'a']
['c', 'a', 'b']
[['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'b', 'c']]
ToklCz
  • 278
  • 3
  • 10
  • Does this answer your question? [List of lists changes reflected across sublists unexpectedly](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) – Tomerikoo Oct 05 '21 at 10:42

2 Answers2

3

You're mutating the same x in place, so only the final version of it is printed after the loop.

result.append(x) does not copy the object (x in this case), it just places a reference to it into the result list.

Do e.g. result.append(x[:]) or result.append(list(x)) to put copies of x into the result list.

AKX
  • 152,115
  • 15
  • 115
  • 172
  • 1
    It's also a bit unintuitive, that the `permutations` function modifies the passed list in-place. (Although, it does go back to the original at the very end.) Still, I'd rather do the copying inside the `permutations` function itself (as in `perm = string[:]`) and you can even skip the second `swap` as you don't need to undo the first one anymore. – Possseidon Oct 05 '21 at 10:30
2

That's why the yielded list has the same references, so whenever you change it, the previous referenced value will be changed, too. The quick fix is to return a copy instance of the list.

def swap(string,x,y):
  string[y], string[x] = string[x], string[y]

def permutations(string ,i=0):
    if i == len(string):
        yield string.copy()

    for x in range(i, len(string)):
        perm = string
        swap(perm,x,i)
        yield from permutations(perm, i+1)
        swap(perm,i,x)

result = []
test = permutations(['a','b','c'])
for x in test:
    print(x)
    result.append(x)

print(result)
mingfei
  • 71
  • 3