While attempting to implement a function that produces all permutations given a list of integers, I’m seeing this behavior where the inserts are not occurring as expected.
My code:
def permute(nums): perms = [[]] for i in range(len(nums)): new_perms = perms * (i + 1) for j in range(len(new_perms)): new_perms[j].insert(j % len(perms), nums[i]) perms = new_perms return perms
When calling permute([1, 2, 3])
I’m expecting the perms to grow like:
[[]] [[1]] [[2, 1], [1, 2] [[3, 2, 1], [1, 3, 2], [2, 1, 3], [3, 1, 2], [2, 3, 1], [1, 2, 3]
However, by the second iteration of the interior loop with new_perms: [[1], [1]]
I’m expecting it to grow to [[2, 1], [1, 2]]
, instead I’m getting [[2,1],[2,1]]
and then [[2,2,1],[2,2,1]]
. On each iteration of the j loop, the number is getting inserted into the current j position of all values of the list simultaneously on each iteration. Not what I was trying to do or expecting.
Ultimately, the code outputs:
[[3,3,3,3,3,3,2,2,1],[3,3,3,3,3,3,2,2,1],[3,3,3,3,3,3,2,2,1],[3,3,3,3,3,3,2,2,1],[3,3,3,3,3,3,2,2,1],[3,3,3,3,3,3,2,2,1]]
Either this is some subtle reference behavior (yay, learn something new!) or I’m just having a really dumb day ;) Any help appreciated.
PLEASE NOTE: I’m NOT asking for help with an alternate or optimal permutations function! I’m trying to figure out why this particular code is behaving in an unexpected way. Thank you.
Advertisement
Answer
Ok, learned a good one here. DEEPCOPY!
import copy def permute(nums): perms = [[]] for i in range(len(nums)): len_perms = len(perms) old_perms = perms perms = [] for _ in range(i+1): perms += copy.deepcopy(old_perms) for j in range(len(perms)): perms[j].insert(j // len_perms, nums[i]) return perms