2013-01-24 10 views
0

我想概括一下我在Github上的Gist中發現的TextRank算法的圖形實現。將滑動窗口與Python中的成對枚舉相結合

基本上它是一個圖形問題,您需要在大小爲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化」的方式?

回答

0

實際上,恕我直言,你有什麼不壞,是相當可讀的。我可以在當前的運行將是辦法改變intermediate_list與看到的唯一的改善是一個generator expression對象,而不是實際的list

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

您可能還希望更改其名稱,以便更好地反映它會那麼可以說,像pair_generatorgen_pairs

順便說一句,它是超越「Pythonic」,以避免prematurely optimizing事情(除非,當然,你只是爲了好玩)。

+0

感謝您的評論,我會根據您的建議將其切換到生成器。我想我的擔心是中間步驟生成重複,然後使用列表(set(..))刪除重複。我已經看到它在很多地方建議,爲了刪除列表中的重複項,您可以簡單地切換到設置,然後返回列表,但不知何故,這讓我有點不安。在其他語言中,您可以輕鬆地在類型之間來回切換。 – nsecord

+0

那麼,從序列切換到類似集合或字典的東西時,項目順序會丟失 - 因此會有一些信息丟失,但這似乎並不是一個問題。還有其他方法可以刪除重複項 - 我相信這是在該步驟中使用集合的目的 - 但如果排序不是問題,則使用集合是最好的方法之一。 – martineau