0

I have written the following function to do list permutations:

def makePermutatedList(original_list,new_list=[]):
    for _ in range(len(original_list)):
        new_list.extend(original_list)
        x=original_list.pop(0)
        original_list.insert(len(original_list),x)
    return new_list

and have saved it into a file called my_list_module.py (which is itself inside of a package called my_modules). Now from another file I import the package/module and run the makePermutatedList():

import my_modules.my_list_module
a=my_modules.my_list_module.makePermutatedList(["jurij","neli","julian"])
print a
b=my_modules.my_list_module.makePermutatedList([1,2,3])
print b

and the output is:

['jurij', 'neli', 'julian', 'neli', 'julian', 'jurij', 'julian', 'jurij', 'neli']
['jurij', 'neli', 'julian', 'neli', 'julian', 'jurij', 'julian', 'jurij', 'neli', 1, 2, 3, 2, 3, 1, 3, 1, 2]

All of the contents of a have been also copied in b although I have called the function 2 times with different arguments. Why is this happening?

EDIT

I actually wanted to use the makePermutatedList() to make a matrix of sound files. I have now corrected the makePermutatedList() as such:

def makePermutatedList(original_list,new_list=None):
    if new_list==None:
        new_list=[]
    for _ in range(len(original_list)):
        new_list.extend(original_list)
        x=original_list.pop(0)
        original_list.insert(len(original_list),x)
    return new_list

This works now as expected inside of other codes for me. However when i use it as below in this specific code i get still the snd_list_A copied in the snd_list_B exactly after the line

snd_list_B=my_modules.my_list_module.makePermutatedList(snd_list_B)

Has anyone any idea why this is still happening? I come nowhere thinking about it:

sample_paths=["/home/amir/Music/SAMPLESWAP_drum_1/DRUMS and SINGLE HITS/toms/",
"/home/amir/Music/sounds/4409__pinkyfinger__piano-notes-1-octave/",
"/home/amir/Music/sounds/pad-snds/",
"/home/amir/Music/sounds/bongo/"]
#SOUNDS
snd_list=[]
#------------
snd_list_A=[]
snd_list_B=[]

for snd in os.listdir(sample_paths[0]):
    snd_list_A.append(sample_paths[0]+snd)
assert len(snd_list_A)==24,"Wrong number of sound files loaded! I need 24 Sound files!sndlist-0"
snd_list_A.sort()
snd_list_A=my_modules.my_list_module.makePermutatedList(snd_list_A)

#~ print "+++++++++++++++++",snd_list_A,len(snd_list_A)
for snd in os.listdir(sample_paths[1]):
    snd_list_B.append(sample_paths[1]+snd)
assert len(snd_list_B)==24,"Wrong number of sound files loaded! I need 24 Sound files!sndlist-1"
snd_list_B.sort()
snd_list_B=my_modules.my_list_module.makePermutatedList(snd_list_B)

print "========================================================"
print id(snd_list_B),id(snd_list_A),snd_list_A is snd_list_B
print "========================================================"

This will print:

========================================================================
140109723798992 140109723798992 True
========================================================================
  • 1
    [`here`](http://docs.python-guide.org/en/latest/writing/gotchas/) it expains what is happening – Praveen Jun 13 '16 at 10:04

1 Answers1

2

This is a pretty common problem when using mutable defaults.
It's happening because default arguments are evaluated at function creation time, which means your function will always be using the exact same list object.

The common workaround is something like:

def some_function(arg=None):
    if arg is None:
        arg = []
    # rest of code
stranac
  • 26,638
  • 5
  • 25
  • 30
  • What does function creation time mean? The first time i call the function there will be a `new_list` set to `[]` and another new empty `new_list` will never be created again? Is that right? –  Jun 13 '16 at 10:05
  • 1
    Not the first time you call it, but when the function definition is executed. But yeah, an empty list won't be created after that, the existing one is reused. – stranac Jun 13 '16 at 10:08
  • I am totally confused! See my EDIT in my question please. –  Jun 13 '16 at 13:27