遍历所有具有间隙的连续项目对



给定一个列表:

mylist = [1,6,4,9,2]

我想返回窗口中所有连续的项目对。
例如,如果我想要 3 个连续项目的对,我可以做:

items=3
for x in range(0,len(mylist)-items+1):
    print(mylist[x:x+items])

哪些输出:

[1, 6, 4]
[6, 4, 9]
[4, 9, 2]

这假设窗口大小也是 3,因此它一次只扫描 3 个索引。
如果我想在 4 个窗口中返回所有 3 对连续的项目,我需要:

[1, 6, 4]
[1, 6, 9]
[1, 4, 9]
[6, 4, 9]
[6, 4, 2]
[6, 9, 2]
[4, 9, 2]

有没有一种简单的方法来生产这些对?

编辑以添加到下面 Alex 的答案:我最终使用组合来识别索引,然后只选择从零开始的索引,如下所示:

from itertools import combinations
def colocate(mylist,pairs=4,window=6):
    x = list(combinations(range(window),pairs))
    y = [z for z in x if z[0]==0]
    for item in y:
        print(item)
">

组合"是与您的问题相关的数学概念。不过,它并不关心"4 号窗口"。

from itertools import combinations
l = [1,6,4,9,2]
for combination in combinations(l, 3):
    print(combination)
(1, 6, 4)
(1, 6, 9)
(1, 6, 2)
(1, 4, 9)
(1, 4, 2)
(1, 9, 2)
(6, 4, 9)
(6, 4, 2)
(6, 9, 2)
(4, 9, 2)

我很好奇你为什么要有一个 4 的窗口。

也许有更好的方法来解决您手头的任务?

一种相当简单的方法是根据索引而不是列表项本身来考虑它。入手:

import itertools
list(itertools.combinations(range(len(mylist)), 3)

这样可以在列表中获得所有可能的索引三元组组合以及列表的长度。现在,您要过滤它们以排除最后一个索引与第一个索引相距 4 个或更多位置的任何索引:

list(filter(lambda seq: (seq[-1] - seq[0]) <= 4, itertools.combinations(l, 3)))

这让你得到你想要的。因此,现在您可以根据 indeces 获得所需的三元组:

[[mylist[i] for i in seq] for seq in filter(lambda seq: (seq[-1] - seq[0]) < 4, itertools.combinations(l, 3))]

它产生:

[[1, 6, 4], [1, 6, 9], [1, 4, 9], [6, 4, 9], [6, 4, 2], [6, 9, 2], [4, 9, 2]]

这非常接近。会有一些重复的产生,但这就是set(...)最后的目的......无论如何应该给你一些想法。

from itertools import combinations, islice, chain
# from itertools examples
def window(seq, n=2):
    "Returns a sliding window (of width n) over data from the iterable"
    "   s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...                   "
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result    
    for elem in it:
        result = result[1:] + (elem,)
        yield result
mylist = [1,6,4,9,2]
set(chain.from_iterable(combinations(w, 3) for w in window(mylist, 4))) 
{(1, 4, 9), (1, 6, 4), (1, 6, 9), (4, 9, 2), (6, 4, 2), (6, 4, 9), (6, 9, 2)}

最新更新