2

I suspect I'm missing something super basic and just looking at this problem wrong so I would be happy if anyone could point me in the right direction. Here's my problem:

I have a list of variables and, for simplicity, they always contain the value. I want to have my code go through all the possible options. Here's the way I quickly thought to do it:

num_apples = 100
num_pears = 100

for current_apple in range(0,num_apples+1):
    for current_pear in range(0, num_pears+1):
        print current_apple, " - ", current_pear

The good thing about this code is I can break out of loops easily(i.e. say I don't want current_apple + current_pear > 50 or something), but the major drawback is I need to know specifically how many variables(fruits in this case) that I'm starting with and often I won't know.

Is there a way to dynamically create the for loop type structure above so I can control when to break a sub loop but without knowing specifically how many variables I'll have ahead of time?

EDIT: Ideally I think it would be easier for me, if I could increase the size of one variable at a time so I can break out of the loop once the variable get out of range that is useful to me.

Lostsoul
  • 25,013
  • 48
  • 144
  • 239
  • 3
    Can't you use recursion? – Colonel Thirty Two Jul 17 '14 at 14:27
  • Recursion is the answer – nagyben Jul 17 '14 at 14:29
  • @ColonelThirtyTwo sorry its been a while, I'll look into recursions. Thanks! – Lostsoul Jul 17 '14 at 14:29
  • `while` may be an even easier option, if you can define what condition should exit the loop. – mdurant Jul 17 '14 at 14:31
  • 1
    You have to know ahead of time what value is "out of range" so you have to have a way to calculate that - even to generate a dynamic portion of code to break there. Given that you can calculate your end goal from your inputs - why can't you just use a standard break in the loops in your example. Or make a base case for a recursive function? – Brandon Buck Jul 17 '14 at 14:33

1 Answers1

8

itertools.product is equivalent to nested for loops.

https://docs.python.org/2/library/itertools.html#itertools.product

>>> import itertools
>>> counts = [1, 2, 3]
>>> ranges = [range(x) for x in counts]
>>> for i in itertools.product(*ranges):
...     print i
... 
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
>>> 
FogleBird
  • 74,300
  • 25
  • 125
  • 131
  • I was thinking of an itertools solution, too, but this doesn't work if you don't know the counts beforehand...which I think is the OP's problem, although it's not very clear. – Tim Pietzcker Jul 17 '14 at 14:37
  • @TimPietzcker You can break out of the loop or stop retrieving elements from the generator if you don't need anymore. – Colonel Thirty Two Jul 17 '14 at 14:38
  • I tried to run it but I'm unsure how to stop a item from growing. For example, say I have 10 items and each item has a range of 10. If the forth item hits 4, how do I stop that item from growing but letting it continue to grow the other numbers? – Lostsoul Jul 17 '14 at 14:40
  • @Lostsoul Break out of the loop? – Colonel Thirty Two Jul 17 '14 at 14:41
  • @ColonelThirtyTwo: How does that allow the other variables to grow? – Tim Pietzcker Jul 17 '14 at 14:43
  • @ColonelThirtyTwo I don't understand how to do that in this case. Say I have a output like this: (0, 0, 0, 0, 1, 3, 9, 9, 9, 9) (0, 0, 0, 0, 1, 4, 0, 0, 0, 0) How can I find that number "4" and say I do not want that item to grow more than 4 while growing the other numbers? – Lostsoul Jul 17 '14 at 14:43
  • @Lostsoul: `if i[4] > 3: continue` – FogleBird Jul 17 '14 at 15:00
  • The `product` function will continue iteration through all combinations but you can simply ignore those combinations that you are not interested in using `continue`. – FogleBird Jul 17 '14 at 15:02
  • @FogleBird cool thanks. Is it possible to have it not iterate the ranges I do not want? or how can I do that? The reason being the ranges I have are very large(50-100 variables with a range of about 1000 each) but once a threshold is reached I won't need any results above that. Is that possible? – Lostsoul Jul 17 '14 at 15:07