【问题标题】:Iterating sublists without using the list length在不使用列表长度的情况下迭代子列表
【发布时间】:2020-08-23 13:21:26
【问题描述】:

我有一个清单,我需要对连续(和重叠)的 3 个元素组进行一些处理:

我可以做到:

for i in range(len(things)-2):
    process(things[i:i+3])

例如:

things=[0, 1, 2, 3, 4, 5, 6, 7]

我想处理:

[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]

但是有没有一种聪明(但可读)的方法可以在不明确使用 len(things) 的情况下做到这一点?

【问题讨论】:

  • 您能否展示一些示例输入和预期输出。

标签: python list iteration


【解决方案1】:

是的,您正在寻找的是一个 滑动/移动 窗口。有不同的方法可以实现这一点,但最简单的是使用来自itertoolstee()islice() 函数。使用它,您可以定义一个 window() 函数,如下所示,默认窗口大小为 2。

import itertools

def window(iterable, n=2):
    iters = itertools.tee(iterable, n)
    for i, it in enumerate(iters):
        next(itertools.islice(it, i, i), None)
    return zip(*iters)

那么你就可以把它当做

>>> things=[0, 1, 2, 3, 4, 5, 6, 7]
>>> list(window(things, n = 3))
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7)]
>>> for elem in window(things, n = 3):
...     print(elem)
... 
(0, 1, 2)
(1, 2, 3)
(2, 3, 4)
(3, 4, 5)
(4, 5, 6)
(5, 6, 7)

编辑:一次使用更简单的选项可能是

>>> list(zip(things, things[1:], things[2:]))
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7)]

【讨论】:

  • 有点矫枉过正,因为我在代码中只需要这个一次,但请接受我的投票:)
  • @xenoid 您可以使用类似zip(things, things[1:], things[2:]) 的东西一次性使用。我已经编辑了帖子以显示结果。
  • @SigmalEpsilon 这确实是您的解决方案让我想到的事情,而且我在两端都有特殊处理,可以通过在三个列表中添加足够的位来很好地实现。我唯一担心的是这会复制列表(其中 IRL 将是 100 到 1000 个元素)。至少这让我不用自己写答案:)
【解决方案2】:

另一种方法可能是:

for i in things[0:-2]:
    a=things.index(i)
    process(things[a:a+3])

【讨论】:

    【解决方案3】:

    让我们尝试使用enumerate,这里len(things[i : i+len_]) == len_ 是删除在迭代结束时累积的不均匀大小的列表。

    len_ = 3
    
    [things[i : i+len_] for i, j in enumerate(things) if len(things[i : i+len_]) == len_]
    
    [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7]]
    

    len_ = 4
    
    [things[i : i+len_] for i, j in enumerate(things) if len(things[i : i+len_]) == len_]
    
    [[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]]
    

    【讨论】:

      猜你喜欢
      • 2018-02-02
      • 1970-01-01
      • 2022-01-23
      • 2017-10-15
      • 2022-01-24
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多