40

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'])
1
  • 1
    Unless this is for your own enrichment, you probably should use itertools.permutations(). Commented Apr 29, 2013 at 3:16

2 Answers 2

55

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'])
Sign up to request clarification or add additional context in comments.

4 Comments

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
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.
@user11580406 this is incorrect. A simple test at the Python command line will prove that list(original) will create a shallow copy of original
If s is a string, why does s[:] produce an object with the same memory address as s according to here. In other words, s is s[:] if s is a string, but if s is an array, s is not s[:]
20
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.