Python:将列表转换为生成器

48
8个回答

71

您确定要创建一个生成器吗?生成器是返回迭代器类型的函数,例如使用yield关键字构造(参见term-generator)。 如果您确实想要这个,steven-rumbalski的答案正是您要找的:

data_gen = (y for y in data)

大多数情况下,您将希望直接创建一个 迭代器 对象,例如使用 next() 方法。在这种情况下,mgilson 上面的注释中已经隐含了答案。
data_iter = iter(data)

这句话的意思是“它相当于data_iter = data.__iter__(),参见functions#iter。”。

44
>>> (n for n in [1, 2, 3, 5])
<generator object <genexpr> at 0x02A52940>

可在Python 2.7.4+中运行

>>> a2g = lambda x : (n for n in x)
>>> a2g([1, 2, 3, 4, 5])
<generator object <genexpr> at 0x02A57CD8>

编辑:

另一种lambda生成器工厂模式的微小变化。

>>> a2g = lambda *args: (n for n in args)
>>> for i in a2g(1, 2, 3, 4, 5): print i

1
2
3
4
5

7
字面上的等价物是:
def data_generator():
    yield 'A'
    yield 'B'
    yield 'C'
    yield 'D'

调用生成器函数会返回一个生成器迭代器。将生成器迭代器传递给列表构造函数,可以得到:

>>> list(data_generator())
['A', 'B', 'C', 'D']

这个生成器迭代器也可以使用生成器表达式创建:

data_iter = (c for c in 'ABCD')

注意:您使用了四个append语句填充了列表。通常情况下,不会这样写。

相反应该这样做:

data = ['A', 'B', 'C', 'D']

5
import itertools
iter_data = itertools.chain(data)

就像这样:
In [10]: data
Out[10]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [11]: iter_data=itertools.chain(data)

In [12]: iter_data
Out[12]: <itertools.chain at 0x1ce8950>

In [13]: iter_data.next()
Out[13]: 1

11
就这个问题而言,“FWIW,this isn't any different than iter_data = iter(data) ... You're not actually chaining anything here.” 的意思是“就这个问题而言,这与iter_data = iter(data)没有任何区别……你实际上并没有链接起来任何东西。” - mgilson
1
不链接任何东西吗?一个人不能拥有单一的链条?;-) - Cameron Sparr
1
@CameronSparr 不行。不行的。._. - code_dredd

2

You could use a generator function:

def gen():
    for x in "ABCD":
        yield x

In [9]: it = gen()

In [10]: next(it)
Out[10]: 'A'

In [11]: next(it)
Out[11]: 'B'

In [12]: next(it)
Out[12]: 'C'

In [13]: next(it)
Out[13]: 'D'

1
>>> d = ['A', 'B', 'C', 'D']
>>> 
>>> def gen(d):
...     for i in d:
...             yield i
... 
>>> for i in gen(d):
...     print i
... 
A
B
C
D
>>> 

能否将其改为闭包?将您的def放在一个函数中,该函数与列表处于同一级别,然后返回包含列表的生成器? - Mark Kortink
@MarkKortink 你可以这样写:gen = lambda d: (i for i in d)。但是,这种写法非常不易读懂,我建议在实际生产代码中避免使用它。 - Kaligule

1
(item for item in listNameHere).next()

如果我没记错的话,这是一般的做法。
>>> a = [0,1,2,3,4]
>>> x = (item for item in a)
>>> x
<generator object <genexpr> at 0x028B8440>
>>> x.next()
0
>>> x.next()
1
>>> x.next()
2

等等等等。


0

https://dev59.com/mGEi5IYBdhLWcg3wIJFH#21622696

在3.x中,这些对象不再附带.next方法; 取而代之的是使用内置的自由函数next:
因此,要创建并遍历生成器或迭代器:
> list_iterator = (d for d in data)  # or list_iterator = iter(data)
> next(list_iterator)
'A'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接