2015-11-27 2 views
2

Итерируя по итератору, я хотел бы избежать конечного пункта и остановиться на предпоследнем пункте - как мне это сделать?Как остановить повторение итератора на предпоследнем элементе?

from itertools import product 
from collections import namedtuple 

param_list = [] 

Parameter = namedtuple("Parameter", ['bad', 'good']) 
param1 = Parameter(["peanut", "gluten"], ["bacon", "pickle"]) 
param_list.append(param1) 
param2 = Parameter([0], [1, 22]) 
param_list.append(param2) 
param3 = Parameter([0, 1], [2, 3, 4, 9]) 
param_list.append(param3) 
param4 = Parameter(["football"], ["running", "yoga"]) 
param_list.append(param4) 

for prod in product(*param_list): # -- I want to skip the last product -- 
    for sub_prod in product(*prod): 
     prod = [str(x) if type(x) is not str else x for x in sub_prod] 
     print ", ".join(prod) 

Примечание -

  1. param_list является переменной длины списка.
  2. Если бы это был список вместо итератора, я бы использовал for prod in product_list[:-1] :
  3. Операция печати предназначена только для иллюстрации.
+0

Вы не можете, потому что вы даже можете создавать бесконечные генераторы. – thefourtheye

+0

Не хотите ли вы вытащить последний элемент из итерации (что вообще невозможно) или просто для того, чтобы избежать повторного использования последнего элемента? – khelwood

+0

@ khelwood - Идеально подходит к самому себе; если это невозможно, просто обнаружите, что это последний элемент и не используйте его. –

ответ

0

ответ Основе @ khelwood в -

from itertools import product 
from collections import namedtuple 

param_list = [] 

Parameter = namedtuple("Parameter", ['bad', 'good']) 
param1 = Parameter(["peanut", "gluten"], ["bacon", "pickle"]) 
param_list.append(param1) 
param2 = Parameter([0], [1, 22]) 
param_list.append(param2) 
param3 = Parameter([0, 1], [2, 3, 4, 9]) 
param_list.append(param3) 
param4 = Parameter(["football"], ["running", "yoga"]) 
param_list.append(param4) 

# Pulling one item ahead of loop so as to avoid the last item. 
iterable = product(*param_list) 
prev_prod = next(iterable) 

for prod in iterable: 
    for sub_prod in product(*prev_prod): # Using 'prev_prod' instead of 'prod' 
     prod_str = [str(x) if type(x) is not str else x for x in sub_prod] 
     print ", ".join(prod_str) 

    prev_prod = prod 
5

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

def skip_last(seq): 
    it = iter(seq) 
    p = next(it) 
    for n in it: 
     yield p 
     p = n 

>>> print (''.join(skip_last('ABCDE'))) 
'ABCD' 

Это генератор который будет перебирать последовательность и выводить каждый элемент, кроме последнего.

0

Используя pairwise рецепт, упомянутый в itertools documentation:

from itertools import tee, izip, imap 
from operator import itemgetter 

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return izip(a, b) 

можно определить

def init(iterable): 
    return imap(itemgetter(0), pairwise(iterable)) 

Это получает вас

>>> list(init(x for x in [1,2,3,4,5])) 
[1, 2, 3, 4] 

 Смежные вопросы

  • Нет связанных вопросов^_^