Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding multiple nested for-loops in python

How to avoid multiple nested for-loops when one nested for-loop has range up to the current iteration of the outer for-loop? For example, consider the following code: This program returns a triplet from a list arr such that arr[i] - arr[j] = arr[j] - arr[k] = d and i<j<k.

d =3
arr = [1, 2, 4, 5, 7, 8, 10]
list1 = []

for biggest in range(0, len(arr)):
    for bigger in range(0, biggest):
        for big in range(0, bigger):
            if abs(arr[big] - arr[bigger]) == d and abs(arr[bigger] - arr[biggest]) == d:
                list1.append([arr[big], arr[bigger], arr[biggest]])
print(list1))

Are there any other alternatives to using multiple nested loops?


2 Answers

You can replace the three loops with:

from itertools import combinations

for big, bigger, biggest in combinations(range(0, len(arr)), 3):

You can replace all the code with:

print([t for t in combinations(arr, 3)
       if t[2] - t[1] == t[1] - t[0] == d])
like image 194
Alex Hall Avatar answered Jun 22 '26 14:06

Alex Hall


You can use the combinations function from itertools. Your code would then become:

from itertools import combinations

d = 3
arr = [1, 2, 4, 5, 7, 8, 10]
list1 = []
for big, bigger, biggest in combinations(arr, 3):
    if abs(big - bigger) == d and abs(bigger - biggest) == d:
        list1.append([big, bigger, biggest])

print(list1)

Which gives the same printout as your code (after you remove the extraneous right parenthesis on your last line):

[[1, 4, 7], [2, 5, 8], [4, 7, 10]]

Note that I changed the meanings of your variables big, bigger, biggest to be the array values rather than their indices. Working with values and avoiding indices is more pythonic and easier to understand.

You could also just do it in a list comprehension, for a slightly different look, avoiding the temporary list, and probable speed increase.

from itertools import combinations

d = 3
arr = [1, 2, 4, 5, 7, 8, 10]
print([[big, bigger, biggest]
        for big, bigger, biggest in combinations(arr, 3)
        if abs(big - bigger) == d and abs(bigger - biggest) == d
    ])
like image 23
Rory Daulton Avatar answered Jun 22 '26 16:06

Rory Daulton