【问题标题】:combining sliding window with pairs enumeration in Python在 Python 中将滑动窗口与对枚举相结合
【发布时间】:2013-01-08 12:20:34
【问题描述】:

我正在尝试根据我在 Github 上的 Gist 中找到的内容来概括 TextRank 算法的图形实现。

基本上这是一个图问题,您需要在大小为 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

这给了我想要的结果,排序并不是真正必要的,但是有没有更优雅的“pythonic”方式来做呢?

【问题讨论】:

    标签: python window iteration tuples


    【解决方案1】:

    实际上恕我直言,您所拥有的内容还不错,而且可读性强。我可以看到它当前运行方式的唯一改进是将intermediate_list 更改为generator expression 对象,而不是实际的list:

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

    您可能还想更改它的名称以更好地反映它,例如pair_generator 或gen_pairs。

    顺便说一句,避免prematurely optimizing 的事情超出了“Pythonic”的范畴(当然,除非你这样做只是为了好玩)。

    【讨论】:

    • 感谢您的评论,我会按照您的建议将其切换为生成器。我想我担心的是中间步骤生成重复项,然后使用 list(set(..)) 删除重复项。我已经在很多地方看到它建议删除列表中的重复项,您可以简单地切换到设置然后返回到列表,但不知何故它让我有点不安。在其他语言中,您很容易在类型之间来回切换时遇到麻烦。
    • 嗯,当从一个序列切换到一个集合或字典之类的东西时,项目顺序会丢失——所以会有一些信息丢失,但这似乎不是一个问题。还有其他删除重复项的方法——我相信这是在该步骤中使用集合的目的——但如果排序不是问题,使用集合是最好的方法之一。
    猜你喜欢
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2014-01-04
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多