31

I am trying to implement an algorithm in Python to generate all Permutations of a list. But I In my for loop I wish to keep the original prefix and rest lists intact, and therefore I am trying to make a copy of those lists using newprefix and newrest, however on printing the variable rest at each iteration, I see that even the variable rest is getting modified! How can I make a shallow copy of the list in Python? Or is there another issue with my attempted logic?

def perm(prefix, rest):
    if len(rest) == 0:
        print prefix 
    for i in range(len(rest)):
        #prints in the for loop are just for debugging
        print "rest:", rest
        print "i=", i
        newprefix = prefix
        newprefix.append(rest[i])
        newrest = rest
        newrest.pop(i)
        print "old pre : ", prefix
        print "newpre=", newprefix
        print "newrest=", newrest
        perm(newprefix, newrest)


perm([], ['a','b','c'])
KT100
  • 1,261
  • 5
  • 17
  • 27

2 Answers2

45

To make a shallow copy, you can slice the list:

newprefix = prefix[:]

Or pass it into the list constructor:

newprefix = list(prefix)

Also, I think you can simplify your code a little:

def perm(prefix, rest):
    print prefix, rest

    for i in range(len(rest)):
        perm(prefix + [rest[i]], rest[:i] + rest[i + 1:])

perm([], ['a','b','c'])
Blender
  • 275,078
  • 51
  • 420
  • 480
  • Your first one (slicing) is my preferred way of accomplishing this. I just thought I'd let them know about the copy module as well. +1 – BlackVegetable Apr 29 '13 at 02:30
  • 3
    Just wondering - isn't the slice operation non-declarative? Isn't it best to clearly declare what you're doing? `copied_list = original_list[:]` doesn't declare that a copy is occurring, whereas `copied_list = copy.copy(original_list)` is highly declarative. – Gershom Maes Nov 18 '15 at 20:35
  • passing a list into the list() constructor does not give a shallow copy of the argument list. – xerxes666 Nov 27 '21 at 15:59
17
import copy

a = [somestuff]
b = copy.copy(a) # Shallow copy here.
c = copy.deepcopy(a) # Deep copy here.

The copy module is worth knowing about. https://docs.python.org/3/library/copy.html

(Python 2) http://docs.python.org/2/library/copy.html

BlackVegetable
  • 11,724
  • 6
  • 50
  • 76