列表或元组的成对遍历

发布于 2024-09-25 17:46:25 字数 177 浏览 4 评论 0原文

a = [5, 66, 7, 8, 9, ...]

是否可以进行迭代而不是这样写?

a[1] - a[0]

a[2] - a[1]

a[3] - a[2]

a[4] - a[3]

...

谢谢你!

a = [5, 66, 7, 8, 9, ...]

Is it possible to make an iteration instead of writing like this?

a[1] - a[0]

a[2] - a[1]

a[3] - a[2]

a[4] - a[3]

...

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

破晓 2024-10-02 17:46:25

使用range就可以了。然而,编程(如数学)是建立在抽象之上的。连续的对[(x0, x1), (x1, x2), ..., (xn-2, xn-1)]称为成对组合。请参阅 itertools 文档中的示例。一旦你的工具集中有了这个函数,你就可以编写:

for x, y in pairwise(xs):
    print(y - x)

或用作生成器表达式:

consecutive_diffs = (y - x for (x, y) in pairwise(xs))

It's ok to use range. However, programming (like maths) is about building on abstractions. Consecutive pairs [(x0, x1), (x1, x2), ..., (xn-2, xn-1)], are called pairwise combinations. See an example in the itertools docs. Once you have this function in your toolset, you can write:

for x, y in pairwise(xs):
    print(y - x)

Or used as a generator expression:

consecutive_diffs = (y - x for (x, y) in pairwise(xs))
定格我的天空 2024-10-02 17:46:25

对于 python 2 中的小列表或 python 3 中的任何列表,您可以使用

[x - y for x, y in zip(a[1:], a)]

更大的列表,

import itertools as it

[x - y for x, y in it.izip(a[1:], a)]

如果您使用的是 python 2

,您可能需要,我会考虑将其编写为生成器表达式,

(x - y for x, y in it.izip(a[1:], a))

这将避免在中创建第二个列表一次性存储所有内容,但您只能迭代一次。如果您只想迭代一次,那么这是理想的选择,并且如果您稍后决定需要随机或重复访问,则很容易更改。特别是如果您要进一步处理它以制作列表,那么最后一个选项是理想的选择。

更新:

迄今为止最快的方法是

import itertools as it
import operator as op

list(it.starmap(op.sub, it.izip(a[1:], a)))

$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]'
100 loops, best of 3: 13.5 msec per loop

$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]'
100 loops, best of 3: 8.4 msec per loop

$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))'
100 loops, best of 3: 6.38 msec per loop

for a small list in python 2 or any list in python 3, you can use

[x - y for x, y in zip(a[1:], a)]

for a larger list, you probably want

import itertools as it

[x - y for x, y in it.izip(a[1:], a)]

if you are using python 2

And I would consider writing it as a generator expression instead

(x - y for x, y in it.izip(a[1:], a))

This will avoid creating the second list in memory all at once but you will only be able to iterate over it once. If you only want to iterate over it once, then this is ideal and it's easy enough to change if you decide later that you need random or repeated access. In particular if you were going to further process it to make a list, then this last option is ideal.

update:

The fastest method by far is

import itertools as it
import operator as op

list(it.starmap(op.sub, it.izip(a[1:], a)))

$ python -mtimeit -s's = [1, 2]*10000' '[x - y for x, y in zip(s[1:], s)]'
100 loops, best of 3: 13.5 msec per loop

$ python -mtimeit -s'import itertools as it; s = [1, 2]*10000' '[x - y for x, y in it.izip(s[1:], s)]'
100 loops, best of 3: 8.4 msec per loop

$ python -mtimeit -s'import itertools as it; import operator as op; s = [1, 2]*10000' 'list(it.starmap(op.sub, it.izip(s[1:], s)))'
100 loops, best of 3: 6.38 msec per loop
触ぅ动初心 2024-10-02 17:46:25

我建议使用很棒的 more_itertools 库,它有现成的 pairwise 函数

import more_itertools

for a, b in more_itertools.pairwise([1, 2, 3, 4, 5]):
    print(a, b)
# 1 2
# 2 3
# 3 4
# 4 5

它可以让你免于编写自己的函数(可能有错误)执行。例如,本页上的大多数实现都不能正确处理空可迭代的情况——生成器函数永远不应该引发 StopIteration,这种行为被视为已弃用 并在 Python 3.6 中导致 DeprecationWarning。它在 Python 3.7 中根本不起作用。

I would recommend to use awesome more_itertools library, it has ready-to-use pairwise function:

import more_itertools

for a, b in more_itertools.pairwise([1, 2, 3, 4, 5]):
    print(a, b)
# 1 2
# 2 3
# 3 4
# 4 5

It will save you from writing your own (likely buggy) implementation. For example, most of implementations on this page don't handle the case with empty iterable correctly -- generator function should never raise StopIteration, this behavior considered deprecated and causes DeprecationWarning in Python 3.6. It won't work in Python 3.7 at all.

箹锭⒈辈孓 2024-10-02 17:46:25

这是来自 itertools reciepes 的示例:

from itertools import tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

可读性不是很好。如果您喜欢更容易理解的内容
了解生成器的工作原理,这里有一个更长的示例,但结果相同:

def pairwise(it):
    """
    Walk a list in overlapping pairs.

    >>> list(pairwise([0, 1, 2, 3, 4, 5]))
    [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
    """
    it = iter(it)
    start = None
    while True:
        if not start:
            start = next(it)
        end = next(it)
        yield start, end
        start = end

Here is the example from the itertools reciepes:

from itertools import tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

Which is not very readable.If you prefer something more understandable and
understand how generators work, here a bit longer example with the same result:

def pairwise(it):
    """
    Walk a list in overlapping pairs.

    >>> list(pairwise([0, 1, 2, 3, 4, 5]))
    [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
    """
    it = iter(it)
    start = None
    while True:
        if not start:
            start = next(it)
        end = next(it)
        yield start, end
        start = end
遗失的美好 2024-10-02 17:46:25

当然。

for i in range(1, len(a)):
    print a[i] - a[i-1]

我看不出真正的问题是什么。您读过Python 教程吗?

Sure.

for i in range(1, len(a)):
    print a[i] - a[i-1]

I fail to see what the real problem is here. Have you read the python tutorial?

自此以后,行同陌路 2024-10-02 17:46:25
def pairwise(iterable):
    i = iter(iterable)
    while True:
        yield next(i), next(i, '')
def pairwise(iterable):
    i = iter(iterable)
    while True:
        yield next(i), next(i, '')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文