【问题标题】:Most pythonic way to get the previous element获取前一个元素的最pythonic方式
【发布时间】:2012-08-22 15:16:09
【问题描述】:

我希望迭代器上有一个类似enumerate 的函数,它会产生(previous_element, current_element) 对。也就是说,鉴于iter

i0, i1, i1, ...

我希望offset(iter) 屈服

(None, i0), (i0, i1), (i1, i2) ...

【问题讨论】:

  • 没有“最pythonic”的方式。您将看到“更 Pythonic”的方式(例如,使用函数而不是具有两个工厂类的类来创建第一个类),但“pythonic”是一个主观想法。
  • 点击其中一个答案下方的✓以接受它。

标签: python iterator


【解决方案1】:

那么简单(明显)的解决方案呢?

def offset(iterable):
    prev = None
    for elem in iterable:
        yield prev, elem
        prev = elem

【讨论】:

  • 对我来说看起来不错,估计我在附近的一个存储库中有非常相似的东西。
  • 我不知道为什么每个人都为这个而跳来跳去itertools。为什么要使用大锤和铁道钉,而图钉就可以了?
  • itertools 是解决一切问题的神秘银弹!
  • +1 为简单起见。最好自己做,而不是浪费时间搜索和询问。
  • @xiaomao -- 同意(部分)。当有一个库函数可以做你想做的事情时,使用它。它会和你想出的任何东西一样好或更好。但是,可读性很重要。一旦你的函数变得难以阅读/破译,你可能应该考虑简化它:)。
【解决方案2】:

将更多的迭代工具放在桌面上:

from itertools import tee, izip, chain

def tee_zip(iterable):
   a, b = tee(iterable)
   return izip(chain([None], a), b)

【讨论】:

    【解决方案3】:
    def pairwise(iterable):
        """s -> (s0,s1), (s1,s2), (s2, s3), ...
        see http://docs.python.org/library/itertools.html
        """
        a, b = itertools.tee(iterable)
        b.next()
        return itertools.izip(a, b)
    

    EDIT将文档字符串移动到函数中

    【讨论】:

    • 第一对不给你(None,i0)
    • @MattH 易于修复;将b.next() 行更改为yield (None, b.next())(然后循环izip 和yield,或者使用Python 3.3 yield from 语法)。
    • @MattH,是的,我知道。我想OP将能够计算出细节。此代码来自文档,被认为是手头问题的提示。
    • 请注意,您的文档字符串应该放在 函数声明之后(适当缩进)。这 will 工作,但你基本上创建一个字符串只是为了再次丢弃它,这使得三重引号字符串看起来像某种形式的块注释(即使你程序在某些情况下会表现相同)。
    • @mgilson,从 8 月开始我就已经知道了。不过,感谢您指出这一点。
    【解决方案4】:
    def offset(iter, n=1, pad=None):
        i1, i2 = itertools.tee(iter)
        i1_padded = itertools.chain(itertools.repeat(pad, n), i1)
        return itertools.izip(i1_padded, i2)
    

    @bpgergo + @user792036 = 这个。两全其美:)。

    【讨论】:

      【解决方案5】:

      我的最佳答案(这需要itertools)是

      def offset(iter, n=1):
          # returns tuples (None, iter0), (iter0, iter1), (iter1, iter2) ...
          previous = chain([None] * n, iter)
          return izip(previous, iter)
      

      但我很想看看是否有人有一个单行(或比此功能的偏移更好的名称)!

      【讨论】:

      • 这在迭代器(与可迭代对象相反)上无法正常工作。例如:list(offset(i for i in xrange(10))) 返回[(None, 0), (1, 2), (3, 4), (5, 6), (7, 8)]
      • 这里的总体思路很好,您只需要使用tee 在给定的迭代器上创建两个独立的迭代器。看我的回答。
      猜你喜欢
      • 2019-10-19
      • 2011-08-24
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多