代码之家  ›  专栏  ›  技术社区  ›  Peter Smit

如何获取列表中生成器的n个next值(python)

  •  36
  • Peter Smit  · 技术社区  · 14 年前

    我制作了一个逐字读取文件的生成器,它工作得很好。

    def word_reader(file):
        for line in open(file):
            for p in line.split():
                yield p
    
    reader = word_reader('txtfile')
    next(reader)
    

    获取列表中n个下一个值的最简单方法是什么?

    5 回复  |  直到 5 年前
        1
  •  46
  •   maxymoo    6 年前

    使用 itertools.islice :

    list(itertools.islice(it, n))
    
        2
  •  11
  •   Beni Cherniavsky-Paskin    6 年前

    编辑 使用 itertools.islice . 我最初提出的下面的模式是坏主意当它崩溃时 it 收益率低于 n 价值观,这种行为依赖于微妙的问题,所以阅读这种代码的人不太可能理解它的精确语义。

    还有

    [next(it) for _ in range(n)]
    

    哪种可能(?)对于不熟悉ITertools的人来说,要更清楚一些;但是如果您经常处理迭代器,ITertools是您的工具集的一个值得添加的部分。

    如果 next(it) 精疲力竭,不断提高 StopIteration ?

    (即何时 少于 n 收益价值)

    几年前我写这句话的时候,我可能认为 停止迭代 会有巧妙的副作用,彻底终止列表理解。但不,整个理解过程将在 停止迭代 向上。(只有当异常源于 range(n) 迭代器。)

    这可能不是你想要的行为。

    但情况更糟。以下应该等同于列表理解(尤其是在Python3上):

    list(next(it) for _ in range(n))
    

    它不是。内部是发电机功能的简写; list() 知道它在上升时就完成了 停止迭代 在任何地方 .
    =>此版本在没有 n 值并返回一个较短的列表。(像 itertools.islice() )

    [执行日期: 2.7 , 3.4 ]

    但那太改变了!当生成器中的任何代码引发时,生成器都会静默退出 停止迭代 是已知的疣,由 PEP 479 . 从python 3.7(或未来导入的3.5)中 RuntimeError 而不是清洁地完成发电机。也就是说,它将类似于列表理解的行为。 (在最近的头部模型上测试)

        3
  •  3
  •   dan_waterworth    14 年前
    for word, i in zip(word_reader(file), xrange(n)):
        ...
    
        4
  •  2
  •   JustAC0der    7 年前

    要获取生成器的前n个值,可以使用 more_itertools.take .

    如果您计划以块的形式迭代单词(例如一次100个),则可以使用更多的itertools.chunked( https://more-itertools.readthedocs.io/en/latest/api.html ):

    import more_itertools
    for words in more_itertools.chunked(reader, n=100):
        # process 100 words
    
        5
  •  0
  •   W.P. McNeill    5 年前

    使用 cytoolz.take .

    >>> from cytoolz import take
    >>> list(take(2, [10, 20, 30, 40, 50]))
    [10, 20]