Jordi van Selm
Jordi van Selm

Reputation: 75

Value appears twice in list after nested for-loops

In my code, I have 3 for-loops. They do what I need them to do, but after I print the list 'z', the wanted value appears twice instead of once.

My code:

x = [200, 100, 50, 20, 10, 5]

z = []
for i in range(0,len(x)):
    for j in range(i+1,len(x)):
        for k in range(i+2,len(x)):
            sum=x[i]+x[j]+x[k]
            if sum%65==0:
                z.append(sum)

print(z)
#out = [260, 260, 130, 130, 65, 65]

More context: My goal is to put all the values of the sum of 3 numbers from list 'x' into a new list 'z' if the sum is divisible by 65 (%65==0)

How can I get the wanted value(s) just to appear once?

Upvotes: 0

Views: 378

Answers (4)

Copperfield
Copperfield

Reputation: 8510

the problem is your range of iteration

>>> for i in range(0,len(x)):
        for j in range(i+1,len(x)):
            for k in range(i+2,len(x)):
                s=x[i]+x[j]+x[k]
                if s%65==0:
                    print(f"{i=}, {j=}, {k=} = {s=}")

                
i=0, j=2, k=4 = s=260
i=0, j=4, k=2 = s=260
i=1, j=3, k=4 = s=130
i=1, j=4, k=3 = s=130
i=2, j=4, k=5 = s=65
i=2, j=5, k=4 = s=65

the k range retrace already traced numbers, make it range from j+1

>>> for i in range(0,len(x)):
        for j in range(i+1,len(x)):
            for k in range(j+1,len(x)):
                s=x[i]+x[j]+x[k]
                if s%65==0:
                    print(f"{i=}, {j=}, {k=} = {s=}")

                
i=0, j=2, k=4 = s=260
i=1, j=3, k=4 = s=130
i=2, j=4, k=5 = s=65
>>> 

Upvotes: 1

Christian Sloper
Christian Sloper

Reputation: 7510

Instead of trying to fix the output as some of the other comments and answers do, lets try to fix the actual code.

When you do this:

for j in range(i+1,len(x)):
        for k in range(i+2,len(x)):

you double count some combinations because both j and k depend on i. (specifically you can reach combinations like 200,50,10 and 200,10,50)

instead do this:

for j in range(i+1,len(x)):
    for k in range(j+1,len(x)):

and the problem is immediately solved.

This isn't very "pythonic" do, so you can probably do better by using the itertools library included in python.

from itertools import combinations

z = [sum(i) for i in combinations(x,r=3) if sum(i)%65 == 0]

Upvotes: 6

zloy_zhake
zloy_zhake

Reputation: 2787

...
for k in range(j+1,len(x)):
...

seems to do the trick.

Upvotes: 0

Mayank
Mayank

Reputation: 1983

You can do this :

print(set(z))

It will eliminate all the repetitions, but the elements of the set will be in a random order. You can read more about Sets here

Upvotes: 1

Related Questions