2
for i in range(0,x):
        for j in range(0,y):
            if (i+j)%2 == 0:

Think of something like tossing two dices at the same time and finding if the sum on the dices is an even number but here's the catch, a dice has 6 sides but here the two can have any number of sizes, equal and not equal even! Can anyone suggest how to merge it under one loop because I can't think of any?

Chandrachud Pati
  • 425
  • 1
  • 5
  • 12
  • What are you *trying to do*? Without context: here's a program that reduces the complexity: `pass` – juanpa.arrivillaga Dec 09 '20 at 08:11
  • We don't know what you're trying to do - for example, what if the condition isn't satisfied? Do you use any of the values? Or do you want to generate only the values of `j` that satisfy the condition? – Thierry Lathuille Dec 09 '20 at 08:13
  • Does this answer your question? [Python Reducing Nested Loops](https://stackoverflow.com/questions/43921489/python-reducing-nested-loops) – Tomerikoo Dec 09 '20 at 08:14
  • What you've written suggests you're working with a grid, and if so then definitely keep it the way it is since its most readable. Turning it into one loop will ultimately have the same complexity (since you'd be using `range(x*y)`) and have an insignificant change in performance :) – dwb Dec 09 '20 at 08:16
  • No, like think of something like tossing two dices at the same time and finding if the sum on the dices is even number but here's the catch, a dice has 6 sides but here the two can have any number of sizes, equal and not equal even! – Chandrachud Pati Dec 09 '20 at 09:13

3 Answers3

2

based on Python combine two for loops, you can merge two for loops in a single line by importing itertools as below:

import itertools

for i, j in itertools.product(range(0,x), range(0,y)):
    if (i+j)%2 == 0:
Ali Ülkü
  • 86
  • 1
  • 9
2

You can't get rid of the nested loop (you could hide it, like by using itertool.product, but it would still be executed somewhere, and the complexity would still be O(x * y)) but you can get rid of the condition, if you only need to generate the values of j that satisfy it, by adapting the range for j.

This way, you'll have about twice as less loops by avoiding the useless ones.

for i in range(0,x):
    for j in range(i%2,y, 2):
        print(i, j, i+j)

Output:

0 0 0
0 2 2
1 1 2
1 3 4
2 0 2
2 2 4
Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
1

For me its much cleaner to leave it as two loops. Its much more readable and easier to understand whats happening. However you could essentially do x * y then use divmod to calculate i and j

x = 2
y = 3
for i in range(0,x):
        for j in range(0,y):
            print(i, j, i+j)

print("###")
for r in range(x*y):
    i, j = divmod(r, y)
    print(i, j, i + j)

OUTPUT

0 0 0
0 1 1
0 2 2
1 0 1
1 1 2
1 2 3
###
0 0 0
0 1 1
0 2 2
1 0 1
1 1 2
1 2 3
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
  • `arr1=[n for n in range(0,a)]` `arr2=[n for n in range(0,b)]` `lst1=list(combinations(arr1, 2))` `lst2=list(combinations(arr2, 2))` `lst=lst1+lst2` `res = list(OrderedDict.fromkeys(lst))` It has an output like this- [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4), (0, 5), (0, 6), (0, 7), (0, 8), (1, 5), (1, 6), (1, 7), (1, 8), (2, 5), (2, 6), (2, 7), (2, 8), (3, 5), (3, 6), (3, 7), (3, 8), (4, 5), (4, 6), (4, 7), (4, 8), (5, 6), (5, 7), (5, 8), (6, 7), (6, 8), (7, 8)] – Chandrachud Pati Dec 09 '20 at 08:45