-1

this is an algorithm that is meant to write down some of the permutations of the list P and it does it well, but...

def p():
    global P
    P = ['a', 'b', 'c', 'd']
    perm(4)

per = []

def perm(k):
    global P
    if k==1:
        print(P)
        per.append(P)
    else:
        for i in range(k):
            P[i], P[k-1] = P[k-1], P[i]
            perm(k-1)
            P[i], P[k-1] = P[k-1], P[i]

when i want it to add the permutations to a global list (necessary for the rest of the program) there is a problem. It still prints all the permutations

['b', 'c', 'd', 'a']
['b', 'c', 'd', 'a']
['d', 'b', 'c', 'a']
['d', 'b', 'c', 'a']
['b', 'd', 'c', 'a']
['b', 'd', 'c', 'a']
['a', 'c', 'b', 'd']
['a', 'c', 'b', 'd']
['b', 'a', 'c', 'd']
['b', 'a', 'c', 'd']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd']
['b', 'd', 'a', 'c']
['b', 'd', 'a', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'd', 'c']
['b', 'a', 'd', 'c']
['b', 'a', 'd', 'c']
['a', 'd', 'b', 'c']
['a', 'd', 'b', 'c']
['b', 'a', 'd', 'c']
['b', 'a', 'd', 'c']
['a', 'b', 'd', 'c']
['a', 'b', 'd', 'c']

but when i check the list it's filled with the default set

[['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b',
'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'],
['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b',
'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'],
['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b',
'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'],
['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c'], ['a', 'b', 'd', 'c']]

could you please help me at least with what's the actual issue?

  • Possible duplicate of [How to clone or copy a list?](https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list) – Patrick Artner Jan 01 '18 at 21:21
  • "when i want it to add the permutations to a global list (necessary for the rest of the program) there is a problem. " It is not necessary, indeed, it is highly unrecommended to rely on global state change. – juanpa.arrivillaga Jan 01 '18 at 21:29
  • you may be able to use the `itertools` module for permutations – dangee1705 Jan 01 '18 at 21:35

3 Answers3

0

Use

   per.append(P[:])

to copy the list. You are appending a reference to a list and thats always the same data. Your per contains the same reference over and over.


Comment-remark of cdarke:

Slicing a list is calles a shallow copy - if you have lists that contain other refs (f.e. inner lists) it will only copy the ref and you have the same problem for the inner lists - you would have to resort to copy.deepcopy in that case.

Example:

innerlist = [1,2,3]
l2 = [innerlist, 5, 6]

l3 = l2[:] 

print(l2)                 # orig
print(l3)                 # the shallow copy
l3[2] = "changed"         # l2[2] is unchanged
print(l2)
print(l3)
innerlist[2] = 999        # both (l2 and l3) will reflect this change in the innerlist
print(l2)
print(l3)

Output:

[[1, 2, 3], 5, 6]            # l2
[[1, 2, 3], 5, 6]            # l3
[[1, 2, 3], 5, 6]            # l2 unchanged  by l3[2]='changed' 
[[1, 2, 3], 5, 'changed']    # l3 changed by  -"-
[[1, 2, 999], 5, 6]          # l2 and l3 affected by change in innerlist 
[[1, 2, 999], 5, 'changed']
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0

It may be more convenient for you to use built-in permutations:

from itertools import permutations

arr = [1, 2, 3]
list(permutations(arr))

> [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
koPytok
  • 3,453
  • 1
  • 14
  • 29
0

Try using built-in itertools link .

import itertools
P = [letter for letter in "abcd"]

def perm(permutate_this):
    return list(itertools.permutations(permutate_this))

print(perm(P))