在Python中结合滑动窗口与对的枚举

0 投票
1 回答
557 浏览
提问于 2025-04-17 13:32

我正在尝试将TextRank算法的图形实现进行一些通用化,参考了我在这个Gist上找到的内容。

简单来说,这是一个图的问题,你需要在一个大小为n的滑动窗口内,为所有节点对创建边。比如说,如果我有一组节点

nodes=[0,1,2,3,4,5,6] 

而窗口大小是n=3,我想要列出一组边

edges=[(0,1), (0,2), (1,2), (1,3), (2,3), (2,4), (3,4), (3,5), ..., (5,6)]

我查看了一些关于滑动窗口的问题(例如,#6998245#6822725),还有关于列出节点对的问题(例如,#1257413#13014595),但不幸的是,我对Python和迭代器的经验不足,无法将它们结合成一个函数。

我想到的解决方案是这个:

from itertools import islice, combinations, chain

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

nodes = [0,1,2,3,4,5,6]

windowed = window(nodes,3)
intermediate_list = [combinations(item,2) for item in windowed]
edges = list(set(chain.from_iterable(intermediate_list)))
edges = sorted(edges)

print edges

这个方案给了我想要的结果,虽然排序并不是特别必要,但有没有更优雅的“Python风格”的做法呢?

1 个回答

0

其实,我觉得你现在的代码还不错,读起来也挺清晰的。唯一我能想到的改进,就是把 intermediate_list 改成一个 生成器表达式,而不是一个真正的 list

intermediate_list = (combinations(item,2) for item in windowed) # outer parentheses required

你可能还想把它的名字改得更贴切一些,比如可以叫 pair_generator 或者 gen_pairs

顺便说一下,避免 过早优化 是非常“Pythonic”的做法(当然,如果你只是为了好玩,那就另当别论了)。

撰写回答