如何交替通过 *multiple 参数的值,而不是可以包含任何迭代器或生成器
Posted
技术标签:
【中文标题】如何交替通过 *multiple 参数的值,而不是可以包含任何迭代器或生成器【英文标题】:how to alternate through values of a *multiple parameter than can include any iterator or generator 【发布时间】:2014-04-28 07:28:59 【问题描述】:假设您被限制使用外部函数,例如 zip 或任何 itertool,您如何通过包含多个迭代器/生成器的参数交替迭代,以便打印每个的第一个索引,然后分别打印第二个、第三个等。
def function(*arguments):
for a in arguments:
iterator = iter(a)
yield next(a)
我一直在试图找出一种方法来找到每个可迭代对象上每个值的下一个索引。到目前为止,我能够打印每个索引的第一个索引,但是在尝试使用 while 循环的 Try 和 except 语句之后,我对如何实现下一步感到困惑。我也对StopIteration
异常在这种情况下如何工作感到困惑。
例如以如下方式使用此函数:
for i in function('123', '4567', '89XY'):
print(i,end='')
将打印:
1,4,8,2,5,9,3,6,X,7,Y
【问题讨论】:
Assuming that your are restricted from using outside functions such as zip or any itertool
- 为什么?
您也不想使用range
之类的东西吗?
你至少可以看看roundrobin
recipe from itertools
;它可以满足您的需求,您可以尝试使用为相关 itertools
函数提供的纯 python 等效项来修改它
'在不使用 zip() 的情况下实现 zip()' 但是为什么呢?这只是代码高尔夫吗?
【参考方案1】:
def function(*args):
it = [iter(x) for x in args]
while True:
more = False
for i in it:
try:
yield(next(i))
more = True
except StopIteration:
pass
if not more:
break
【讨论】:
你能解释一下为什么这里需要捕获并传递StopIteration异常吗? @user2918863 因为您的某些可迭代对象可能会在其他可迭代对象之前用完(例如您的示例中的'123'
)。
还有一个特定的名称用于创建控制结构,例如使用 more= False 创建的控制结构,以便在最后 2 个代码块中的某个点跳出循环?我真的在编程的这方面很挣扎,并想进一步研究它【参考方案2】:
itertools 文档的方法具有纯 python 等效项。在这种情况下,izip
就是您所寻求的:
def izip(*iterables):
# izip('ABCD', 'xy') --> Ax By
iterators = map(iter, iterables)
while iterators:
yield tuple(map(next, iterators))
并使用(字符串可迭代):
for i in izip('abc', '123', 'pqr'):
print i
产量
('a', '1', 'p')
('b', '2', 'q')
('c', '3', 'r')
【讨论】:
izip_longest
,鉴于 OP 的输入长度不同【参考方案3】:
可能是这样的:
def function(*args):
iters = map(iter, args)
while iters:
for iter_arg in iters:
try:
yield iter_arg.next()
except StopIteration:
iters.remove(iter_arg)
【讨论】:
在迭代列表时不能安全地从列表中删除以上是关于如何交替通过 *multiple 参数的值,而不是可以包含任何迭代器或生成器的主要内容,如果未能解决你的问题,请参考以下文章
添加迁移时,IdentityServer DB 上的 EF Core 迁移适用于 MULTIPLE 表而不是仅 AspNetUsers 表
渲染power-select-multiple后如何关注输入?
如何使用 Dlookup for Multiple Criteria 创建动态组合框
如何清除 react-multiple-datepicker 中的值?