如何在倒数第二项停止迭代迭代器?
How to stop iterating over an iterator at the penultimate item?
在遍历迭代器时,我想避开最终项并停在倒数第二项 - 我该怎么做?
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)
备注 -
- param_list 是可变长度列表。
- 如果它是一个列表而不是一个迭代器,我会使用
for prod in product_list[:-1] :
- 打印语句仅供参考。
要避免使用最后一项(但不能避免拉最后一项,这通常是不可能的),你可以这样做像这样:
def skip_last(seq):
it = iter(seq)
p = next(it)
for n in it:
yield p
p = n
>>> print (''.join(skip_last('ABCDE')))
'ABCD'
这是一个生成器,它将遍历序列并生成除最后一项以外的所有项目。
基于@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
使用 itertools
documentation 中提到的 pairwise
配方:
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]
在遍历迭代器时,我想避开最终项并停在倒数第二项 - 我该怎么做?
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)
备注 -
- param_list 是可变长度列表。
- 如果它是一个列表而不是一个迭代器,我会使用
for prod in product_list[:-1] :
- 打印语句仅供参考。
要避免使用最后一项(但不能避免拉最后一项,这通常是不可能的),你可以这样做像这样:
def skip_last(seq):
it = iter(seq)
p = next(it)
for n in it:
yield p
p = n
>>> print (''.join(skip_last('ABCDE')))
'ABCD'
这是一个生成器,它将遍历序列并生成除最后一项以外的所有项目。
基于@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
使用 itertools
documentation 中提到的 pairwise
配方:
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]