2016-01-26 4 views
0

Я пытаюсь создать рекурсивный генератор, но я явно ничего не вижу. В основном у меня есть список положительных и отрицательных значений для конкретных измерений гистограммы, и вы хотите получить каждую комбинацию положительных и отрицательных. Ex:Рекурсивный генератор Python

input = [[-1,2],[-3,4],[-5,6]] 

И результат мне нужно (хотя я хочу, чтобы это как генератор вместо списка, но вы получите идею):

output = [[-1, -3, -5],[-1, -3, 6],[-1, 4, -5],[-1, 4, 6],[2, -3, -5],[2, -3, 6],[2, 4, -5],[2, 4, 6]] 

я сумел сделать это , но только путем добавления элементов в глобальный список внутри моей рекурсии, но я действительно надеялся, что смогу просто сделать это с генератором и перебрать мою функцию, поскольку это сделает его настолько чистым ИМО.

Вот что я сейчас:

def combs(idx,array,current=[]): 
    for item in array[idx]: 
     current_copy = current[:] 
     current_copy.append(item) 
     if idx + 1 < len(array): 
      combs(idx+1,array,current_copy) 
     else: 
      print current_copy 
      # yield current_copy 

Это напечатает именно то, что я хочу, но когда я пытаюсь изменить шрифт на выход и цикл по функции она не работает. (Например)

for item in combs(0,input,[]): 
    print item 
+2

Пожалуйста, избегайте вызова переменных с именами функций ('input' в этом случае), это даст вам головные боли –

ответ

1

Если вы используете Python 3.3 или более поздней версии, вы хотите yield from заявление:

def combs(idx,array,current=[]): 
    for item in array[idx]: 
     current_copy = current[:] 
     current_copy.append(item) 
     if idx + 1 < len(array): 
      yield from combs(idx+1,array,current_copy) 
     else: 
      yield current_copy 

В Python 2.7, вы можете расширить yield from в петлю:

def combs(idx,array,current=[]): 
    for item in array[idx]: 
     current_copy = current[:] 
     current_copy.append(item) 
     if idx + 1 < len(array): 
      for i in combs(idx+1,array,current_copy): 
       yield i 
     else: 
      yield current_copy 
+0

Я использую 2.7, есть ли подобная альтернатива? – KevinShaffer

+0

, вы должны иметь возможность перебрать рекурсивный вызов '' combs'' и получить отдельные значения –

+0

Я попытался выполнить то, что у меня выше, за исключением переключения print_ current_copy, чтобы получить current_copy, и я не получаю никакого вывода. – KevinShaffer

2

Другим вариантом для этой задачи является функция itertools.product:

>>> from itertools import product 
>>> input = [[-1,2],[-3,4],[-5,6]] 
>>> list(product(*input)) 
[(-1, -3, -5), (-1, -3, 6), (-1, 4, -5), (-1, 4, 6), (2, -3, -5), (2, -3, 6), (2, 4, -5), (2, 4, 6)] 
+0

Это замечательно и решает общую проблему! Мне все еще интересно, почему то, что я пытаюсь сделать, не работает, хотя :( – KevinShaffer

+0

Если он хочет, генератор должен делать 'myGenerator = product (* myInput)'. –

+1

@ Mr.E Правильно, я использовал 'list () ', чтобы продемонстрировать результат. – glibdud