I was going through this post trying to learn more about permutations: Finding all possible permutations of a given string in python
And I got stuck on this code:
def permutations(string, step = 0):
# if we've gotten to the end, print the permutation
if step == len(string):
print "".join(string)
# everything to the right of step has not been swapped yet
for i in range(step, len(string)):
# copy the string (store as array)
string_copy = [character for character in string]
# swap the current index with the step
string_copy[step], string_copy[i] = string_copy[i], string_copy[step]
# recurse on the portion of the string that has not been swapped yet (now it's index will begin with step + 1)
permutations(string_copy, step + 1)
I'm not understanding the line where we swap the current index with the step, what exactly is this doing? I know that we move to the right once sith step
but how does string_copy[step], string_copy[i] = string_copy[i], string_copy[step]
aid that? I've just no idea what's happening
This is a nice piece of code. The swap is the step creating a different permutations here. I tried running this with 2 additional print statements like below:
The result of the run is as below:
If you observe the first pass returns 'abc' itself as step matches i making the swap trivial. Then b and c get swapped to create acb and so on.
a,b = b,a
is a Python idiom for swapping two values, it can also be written:Inside the for loop, above permutations(...), add this line:
Now it will show you the inner workings as it runs:
I'm finding it hard to make an example that adds any more clarity. How about this:
-- a
, the second part is all things under-- b
, the third part is all things under-- c
.--a
start with-- a
. All things under-- ab
start with-- ab
.and, to try and answer your comment questions:
The line
for i in range(step, len(string)):
starts the index counter from the current indent / step level. That's why it goes from (1,1) to (2,2) at a deeper level. You can see that when we come back from (2,2) we pick up the previous state (1,1) and at the same level go to (1,2), then into (2,2) at a deeper level under there.The reason we go from (2,2) back to (0,0) is because we've got to the end of the string by indenting to the right, as many times as we can, until we've run out of permutations starting with 'a'. 'abc' and 'acb' Then we go back to the start, starting with 'b'. 'bac' and 'bca'. Then we've run out, go back to the start.
e.g.
At every level, the same pattern is happening. Change this column/level, and repeat all the lower levels. It's a self-similar, recursive, loopy pattern.
I have 8 versions of
print
statements in my example code, printing different combinations of things to try and show what's going on. I decided the above is the most clear, but I encourage you to put print statements in and re-run it. Print 'string' and 'string_copy' before and after the swap, print 'string_copy[step:]' and print" "*(3*(step+1))
to print indents.There's no easy explanation that I know of. There's no substitute for staring at the code, working through it bit by bit over and over until it makes more sense.