【问题标题】:How to refer to next element in a loop?如何引用循环中的下一个元素?
【发布时间】:2014-04-08 02:26:30
【问题描述】:

我一直在寻找这个,但找不到我想要的。我确定我以前见过这样做,但我似乎找不到它。这是一个例子:

在这种情况下,我想取数组中每个元素的差异,

#Generate sample list
B = [a**2 for a in range(10)]
#Take difference of each element
C = [(b+1)-b for b in B]

(b+1) 是表示数组中的下一个元素,我不知道该怎么做,显然不起作用,给出结果:

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

我想要的结果是:

 [1, 3, 5, 7, 9, 11, 13, 15, 17]

我知道这个结果比原始数组短,但是这样做的原因是替换丑陋的表达式,例如:

 C = [B[i+1]-B[i] for i in range(len(B)-1)]

在这种情况下,它确实没有那么糟糕,但是在某些情况下,我需要使用长表达式遍历多个变量,并且每次都必须编写索引会很烦人。现在我希望有一种我不知道的简单的pythonic方法来做到这一点......

编辑:我的意思是必须对多个变量执行此操作的一个示例是:

 X = [a for a in range(10)]
 Y = [a**2 for a in range(10)]
 Z = [a**3 for a in range(10)]

 for x,y,z in zip(X,Y,Z):
     x + (x+1) + (y-(y+1))/(z-(z+1))

其中 (x+1),(y+1),(z+1) 表示下一个元素,而不是:

 for i in range(len(X)):
     x[i] + x[i+1] + (y[i]-y[i+1])/(z[i]-z[i+1])

我正在使用 python 2.7.5 顺便说一句

【问题讨论】:

    标签: python arrays list for-loop iterator


    【解决方案1】:

    回复:您的编辑

    zip 仍然是正确的解决方案。您只需要将列表上的两个迭代器压缩在一起,其中第二个应该提前一个刻度。

    from itertools import izip,tee
    
    cur,nxt = tee(izip(X,Y,Z))
    
    next(nxt,None) #advance nxt iterator
    
    for (x1,y1,z1),(x2,y2,z2) in izip(cur,nxt):
        print x1 + x2 + (y1-y2)/(z1-z2)
    

    如果您不喜欢内联的next 调用,可以使用islice,就像@FelixKling 提到的那样:izip(cur,islice(nxt, 1, None))

    【讨论】:

    • 在 python 版本 2.7.5 上,它适用于 zip 或 izip。实际上,我比@FelixKling 提到的方法更喜欢这种方法,但对每个人来说都是他自己的方法。谢谢!
    • @user2593236:澄清一些事情:这和我的版本一样,只是应用于多个列表。如果这是你的用例,当然你应该使用这个解决方案:) 关于 zip 和 izip:我们建议使用izip,因为在 Python 2 中,zip 立即处理所有参数并返回一个新列表。 IE。它基本上创建了所有输入列表的副本,这通常是不需要的。 izip 而是返回一个生成器,以便每个“压缩”元素仅在请求时生成。两者都在 Python 2 中运行良好,只是工作方式略有不同。
    【解决方案2】:

    您可以使用zip 来创建当前值、下一个值的元组:

    C = [b - a for a, b in zip(B, B[1:])]
    

    我相信zip 在 Python 3 中返回一个生成器。在 Python 2 中,您可能想要使用 izip。而B[1:],你可以使用isliceislice(B, 1, None)

    【讨论】:

    • 我使用 python 2.7,我可以确认与 python3 相同的方法也适用于 python2
    • @sshashank124 这些答案适用于一个列表,但我正在寻找一种更通用的方法来执行此操作,该方法将允许遍历多个列表,同时能够引用中的下一个/上一个元素每个列表也许我应该在问题中举一个例子
    • 关于 zip 在 python3 中返回生成器是正确的。我开始使用的替代方法是from future_builtins import zip,而不是itertools.izip。我认为该版本适用于 python2.x 和 3.x
    • @user2593236:是的,也许你应该这样做。但是,如果您有多个列表,那么 zip 仍然可以作为解决方案。
    【解决方案3】:

    也许你想要enumerate。如下:

    C = [B[b+1]-item for b,item in enumerate(B[:-1])]
    

    或者简单地说:

    C = [B[b+1]-B[b] for b in range(len(B[:-1]))]
    

    它们都有效。

    示例

    >>> B = [a**2 for a in range(10)]
    >>> C = [B[b+1]-item for b,item in enumerate(B[:-1])]
    
    >>> print C
    [1, 3, 5, 7, 9, 11, 13, 15, 17]
    

    【讨论】:

      【解决方案4】:

      这是一种很奇怪的方法,但它确实有效!

      b = [a**2 for a in range(10)]
      print b
      print reduce(lambda x, y:len(x) and x[:-1]+[y-x[-1], y] or [y], b, [])
      

      我在 CodeBunk 上创建了一个铺位,所以你也可以运行它

      http://codebunk.com/b/-JJzLIA-KZgASR_3a-I8

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 2016-03-06
        • 2010-09-24
        • 2010-09-24
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多