可重用的可迭代语法?

时间:2019-01-16 00:01:56

标签: python python-2.7 syntax iterator iterable

使用生成器理解时,只能使用一次迭代。例如。

signal sqlstate '12345'
    set message_text = '::SOME CUSTOM ERROR::'

考虑到工作原理与列表理解方法不同,这很烦人。

您可以执行>>> g = (i for i in xrange(10)) >>> min(g) 0 >>> max(g) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: max() arg is an empty sequence 使其可重用,但随后您必须执行g = lambda (): (i for i in xrange(10))而不是g ()(编辑:问题不在于g输入的时间太长,但是如果函数期望可迭代,则不能告诉它执行g ()而不是g ())。你也可以做

g.__iter__()

,但这比键入class gObject(object): def __iter__(self): return (i for i in xrange(10)) g = gObject() 的时间长得多。完成此任务的语法比g = (i for i in xrange(10))短吗?

注意:

  • 我们可以假设可迭代对象不会消耗其他永久可迭代对象中的元素。例如,如果我做了gObject,则不会尝试定义z = iter(xrange(10)),因为它只能工作一次(不克隆g = (i for i in z))。
  • z将不再是迭代器。相反,它现在将是迭代的。我很好。确实,这就是重点。
  • 它应适用于无限迭代。例如,列表推导将不起作用,因为它仅在有限的情况下起作用。
  • 我们可以假设任何初始化成本都很便宜,因此重新运行定义g的代码将不是问题。

2 个答案:

答案 0 :(得分:1)

我没有完全遵循注释,但是itertools.tee可以给我多个可迭代项:

In [518]: g1,g2,g3 = itertools.tee((i for i in range(10)), 3)
In [519]: min(g1), max(g2)
Out[519]: (0, 9)
In [520]: a = 0
In [521]: while a<10:
     ...:     a += next(g3)      # simulate an infinite sequence
     ...:     
In [522]: a
Out[522]: 10
In [523]: list(g3)
Out[523]: [5, 6, 7, 8, 9]

或者不打开包装:

def foo(g):
    a=0
    while a<12:
        a += next(g)
    return (a, list(g))

In [525]: alist = itertools.tee((i for i in range(10)),3)
     ...: flist = [min, max, foo]
     ...: for f,a in zip(flist, alist):
     ...:     print(f(a))
0
9
(15, [6, 7, 8, 9])

(正在使用Py3)

答案 1 :(得分:-1)

没有,没有一种语法更简洁,因为您要的是一个非常特殊的情况,而不是Python选择为其提供特殊支持的情况。