1

My function combinations(ary, p) is suposed to return every possible combination, of order of items in list. But it always returns the first value multiple times, even tho it finds all the possible orders, which I know because it prints them.
EDIT: I would like to make it work my self, learn something and not use any external libs.

def combinations(ary, p):
    ln = len(ary)
    bary=[]
    for a in range(ln-p):
        if p<ln-2:
            bb = combinations(ary, p+1)
            for be in bb:
                bary.append(be)
        if p>=ln-2:
            bary.append(ary)
        ary.append(ary.pop(p))
    return bary


Another version with debug print() functions. I will give its sample output.

def combinations(ary, p):
    ln = len(ary)
    bary=[]
    for a in range(ln-p):
        if p<ln-2:
            bb = combinations(ary, p+1)
            for be in bb:
                bary.append(be)
        if p>=ln-2:

    -->     bary.append(ary)
    -->     print('ary', ary, 'bary', bary)

        ary.append(ary.pop(p))
    return bary

Console output after running with combinations([7,3,2], 0)::

##  There is clearly every possible combination:
##
##      ||
##      ||
        \/
ary [7, 3, 2] bary [[7, 3, 2]]
ary [7, 2, 3] bary [[7, 2, 3], [7, 2, 3]]
ary [3, 2, 7] bary [[3, 2, 7]]
ary [3, 7, 2] bary [[3, 7, 2], [3, 7, 2]]
ary [2, 7, 3] bary [[2, 7, 3]]
ary [2, 3, 7] bary [[2, 3, 7], [2, 3, 7]]
[[7, 3, 2], [7, 3, 2], [7, 3, 2], [7, 3, 2], [7, 3, 2], [7, 3, 2]]


The last list is suposed to include every possible order, but it has only the input value order even tho it prints every order. So where did I mess up the return?

2
  • why not just use itertools here print(list(itertools.permutations([7,3,2]))) Commented Mar 5, 2020 at 19:32
  • If I won't be able to fix it I will eventualy have to, but I won't learn anything and I would prefer to make it as much myself as possible. Commented Mar 5, 2020 at 19:35

1 Answer 1

1

Your issue is there is only one copy of ary. You append it to bary many times. So bary is full of the same one list. Any time you make a change to ary. That will be reflected in all of them cause they are all the same list.

Instead when you append to bary assign a copy of ary but as a new list of its own so it wont be affected when you change ary

def combinations(ary, p):
    ln = len(ary)
    bary=[]
    for a in range(ln-p):
        if p<ln-2:
            bb = combinations(ary, p+1)
            for be in bb:
                bary.append(be)
        if p>=ln-2:
            bary.append(ary[:]) #Changed this line to take a shallow copy of ary
            print('ary', ary, 'bary', bary)

        ary.append(ary.pop(p))
    return bary

print(combinations([7,3,2], 0))

OUTPUT

ary [7, 3, 2] bary [[7, 3, 2]]
ary [7, 2, 3] bary [[7, 3, 2], [7, 2, 3]]
ary [3, 2, 7] bary [[3, 2, 7]]
ary [3, 7, 2] bary [[3, 2, 7], [3, 7, 2]]
ary [2, 7, 3] bary [[2, 7, 3]]
ary [2, 3, 7] bary [[2, 7, 3], [2, 3, 7]]
[[7, 3, 2], [7, 2, 3], [3, 2, 7], [3, 7, 2], [2, 7, 3], [2, 3, 7]]
Sign up to request clarification or add additional context in comments.

2 Comments

Maybe add that bary is full of references to ary?
Huge thanks, I would have never thought that this is what was happening. I woud have gave you upvote but I have not enough points.

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.