Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
reduce nested for-loops
#1
Hi,

i have lots of "search"-loops which looks like this:
            for b in a.list_of_bs:
                for c in b.list_of_cs:
                    for d in c.list_of_ds:
                        do_something()
This is a clear code smell. So how could this be simplified. Any idea?
Reply
#2
The code doesn't look awful to me. But you want to do something for each "d", and those are nested way down inside a hierarchical datastructure. If you need to do this with any frequency, the items should be more accessible.

In isolation, it's hard to make suggestions. But perhaps you should instead have a collection of objects, each of which has the "b", "c" and "d" information. Then you can just iterate over that collection.

So I'd focus on the data and the data layout, not the specific set of loops shown.
Gribouillis likes this post
Reply
#3
Yes, you can:

from itertools import product


for a, b, c in product(a.list_of_bs, b.list_of_cs, c.list_of_ds):
    do_something(a, b, c)
Docs: itertools.product
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
(Mar-15-2023, 11:30 AM)DeaD_EyE Wrote: Yes, you can:

from itertools import product


for a, b, c in product(a.list_of_bs, b.list_of_cs, c.list_of_ds):
...

I don't think "b" or "c" are separately available objects (since they're just the loop variables in the original code).
Reply
#5
Plus the OP wants to dig down to list_of_ds, not create tuples.
Reply
#6
(Mar-15-2023, 11:30 AM)DeaD_EyE Wrote: Yes, you can:

from itertools import product


for a, b, c in product(a.list_of_bs, b.list_of_cs, c.list_of_ds):
    do_something(a, b, c)
Docs: itertools.product

This didnt work, since the "xxx is referenced before assignment" error occurs.
Reply
#7
(Mar-15-2023, 02:35 PM)bowlofred Wrote: I don't think "b" or "c" are separately available objects (since they're just the loop variables in the original code).

I saw it too late. The names of the objects are a, b, c which do have the attribute list_of_xx. After the first iteration, the names are rebound to the elements from those three objects. This fails.

Better example:

from itertools import product


card_colors = "♥♦♠♣"
card_values = list(map(str, range(1, 11)))
card_values += "KJQ"

for color, value in product(card_colors, card_values):
    print(f"{color} {value}")
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
(Mar-14-2023, 09:24 PM)bowlofred Wrote: The code doesn't look awful to me.

OK, accepting this. But normally i have more that only 3 nested loops. When there's > 8, the pylint complains about it.
Reply
#9
If your code is so deep nested, there is maybe a different problem.
If the structure is deep nested, you could also create a list/tuple with all elements, which should be used for product-iteration.
Then you can call product(*arguments).

from itertools import product

my_range1 = range(3)
my_range2 = range(2)
my_range3 = range(4)
my_range4 = range(2)

my_ranges = (my_range1, my_range2, my_range3, my_range4)
for values in product(*my_ranges):
    print(values)
But maybe you can solve your problem differently (XY-Problem?).
bowlofred likes this post
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#10
Depending on what do_something looks like, there is always list comprehension...

alist = [1,2,3]
blist = [4,5,6]
clist = [7,8,9]

print([element_c for element_c in clist for element_b in blist for element_a in alist])
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Adding values with reduce() function from the list of tuples kinimod 10 2,677 Jan-24-2023, 08:22 AM
Last Post: perfringo
  Nested for loops: Iterating over columns of a DataFrame to plot on subplots dm222 0 1,726 Aug-19-2022, 11:07 AM
Last Post: dm222
  Nested for loops - help with iterating a variable outside of the main loop dm222 4 1,605 Aug-17-2022, 10:17 PM
Last Post: deanhystad
  breaking out of nested loops Skaperen 3 1,233 Jul-18-2022, 12:59 AM
Last Post: Skaperen
  Break out of nested loops muzikman 11 3,384 Sep-18-2021, 12:59 PM
Last Post: muzikman
  How to break out of nested loops pace 11 5,413 Mar-03-2021, 06:25 PM
Last Post: pace
  Nested for Loops sammay 1 8,803 Jan-09-2021, 06:48 PM
Last Post: deanhystad
  How do I reduce the time to Invoke Macro via Python? JaneTan 1 2,141 Dec-28-2020, 06:46 AM
Last Post: buran
  How to reduce the following code to run in sequence? Giggel 4 2,685 Jun-28-2020, 01:31 AM
Last Post: Giggel
  How to make this function general to create binary numbers? (many nested for loops) dospina 4 4,445 Jun-24-2020, 04:05 AM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020