Python 是否有一些内置的标记序列的最后一个?
我需要这样的东西:Python 是否有一些内置的标记序列的最后一个?,python,generator,Python,Generator,我需要这样的东西: >>> for i in mark_last([1, 2, 3]): ... print(i) ... (1, False) (2, False) (3, True) 我是这样实现的,但是 def mark_last(li): items = iter(items) try: prev = next(items) except StopIteration: return for item
>>> for i in mark_last([1, 2, 3]):
... print(i)
...
(1, False)
(2, False)
(3, True)
我是这样实现的,但是
def mark_last(li):
items = iter(items)
try:
prev = next(items)
except StopIteration:
return
for item in items:
yield prev, False
prev = item
yield prev, True
有内置的吗?还是用一种较短的方法?可能是与
itertools.groupby()相结合的东西
?-不接受使用len()
的技巧,因为它们不适用于生成器。您可以根据iwindow
定义mark\u last
,它返回一个滑动参数
一个小房间的窗户
import itertools as IT
def iwindow(iterable, n=2):
"""
Returns a sliding window (of width n) over data from the sequence.
s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...
"""
iterables = IT.tee(iterable, n)
iterables = (IT.islice(it, pos, None) for pos, it in enumerate(iterables))
for result in IT.izip(*iterables):
yield result
def mark_last(iterable):
for i, j in iwindow(iterable):
yield i, False
yield j, True
for i in mark_last([1, 2, 3]):
print(i)
屈服
(1, False)
(2, False)
(3, True)
请注意,通过在Python3中传递对mark_last
的需要,您可能可以直接解决iwindow
的问题+
对于大型列表,这可能对性能有点困难
>>> def mark_last(iterable):
... *others, last = iterable
... for element in others:
... yield (element, False)
... yield (last, True)
...
>>> for i in mark_last([1, 2, 3]):
... print(i)
...
(1, False)
(2, False)
(3, True)
:
如果目标列表包含一个前缀为星号的目标,
称为“星号”目标:该对象必须是至少具有
目标列表中目标的数量减去一最新版本
序列的第一项从左到右分配给
目标在星号目标之前。序列的最后一项是
分配给星号目标之后的目标。名单
然后将序列中的剩余项目分配给星号目标
(列表可以为空)
这是在*others,last=iterable
行上执行的操作,但相反
是否有一些内置的标记序列的最后一个
不,没有
您的功能很好,除了两点:
raisestopIteration
,而应该break
;最终,raisestopIteration
将导致运行时错误
()一个更简洁的版本就是你所给予的
def mark_last(items):
items = iter(items)
prev = next(items)
for item in items:
yield prev, False
prev = item
yield item, True
请注意,使用裸
next
来引发StopIteration
是不可取的,但是,您可能希望使用显式try…除了
确实不会使代码变短,但也许这不应该是目标iwindow
是一种更常用的设计模式。如果将iwindow
保存在工具箱中(例如,在util.py
模块中),就可以解决许多滑动窗口问题mark_last
只是一个例子。你的2号就是一个很好的例子。关于1号:空序列→ 无元素→ 没有最后的元素→ 无需标记因此,根据设计,打印循环根本不被输入。@RobertSiemer:如果你看一下mark_last
:last=next(li)
——这与第2行的问题相同:它现在可以工作了,但在后PEP479时代不会。是否存在无限迭代器的最后一个元素?如果您知道有可能在无限迭代器上调用此函数,您应该使用Veedrac的解决方案。是的,for…in
更好。我将编辑我的问题。