给定一个列表:
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)}