2017-02-14 45 views
0

我有一個指定流的跳轉列表(源跳轉到與他們各自的體積destionation)。 現在我想分割這些流到鏈接(例如(來源跳與音量,跳到目的地與音量),併合並所有重複的鏈接在一起,總結他們的體積Python減少基於匹配鍵/值對的Dicts列表

因爲我是新來的蟒蛇我'我想知道一個好的方法是什麼,我的第一種方法是循環遍歷所有的流程,並在內部的所有鏈接中嵌套一個循環,並檢查鏈接是否已經存在

但是,如果我有數以百萬計的流量,

我的起始資料看起來像這樣:

flows = [ 
    { 
     'source': 1, 
     'hop': 2, 
     'destination': 3, 
     'volume': 100, 
    },{ 
     'source': 1, 
     'hop': 2, 
     'destination': 4, 
     'volume': 50, 
    },{ 
     'source': 2, 
     'hop': 2, 
     'destination': 4, 
     'volume': 200, 
    }, 
] 

什麼我的結果應該是:

links = [ 
    { 
     'source': 1, 
     'hop': 2, 
     'volume': 150, 
    },{ 
     'hop': 2, 
     'destination': 3, 
     'volume': 100, 
    },{ 
     'hop': 2, 
     'destination': 4, 
     'volume': 250, 
    },{ 
     'source': 2, 
     'hop': 2, 
     'volume': 200, 
    }, 
] 

非常感謝您的幫助!

+1

[python pandas](http://pandas.pydata.org/)是你的朋友 – Craicerjack

回答

2

您可以收集的鏈接到兩個不同的字典,一個源&跳和跳數&目的地之間的另一個之間。然後,您可以輕鬆地從兩個字典中分別創建結果列表。下面Counter使用哪個是dict像0對象作爲默認值:

import pprint 
from collections import Counter 

flows = [ 
    { 
     'source': 1, 
     'hop': 2, 
     'destination': 3, 
     'volume': 100.5, 
    },{ 
     'source': 1, 
     'hop': 2, 
     'destination': 4, 
     'volume': 50, 
    },{ 
     'source': 2, 
     'hop': 2, 
     'destination': 4, 
     'volume': 200.7, 
    }, 
] 

sources = Counter() 
hops = Counter() 

for f in flows: 
    sources[f['source'], f['hop']] += f['volume'] 
    hops[f['hop'], f['destination']] += f['volume'] 

res = [{'source': source, 'hop': hop, 'volume': vol} for (source, hop), vol in sources.items()] 
res.extend([{'hop': hop, 'destination': dest, 'volume': vol} for (hop, dest), vol in hops.items()]) 
pprint.pprint(res) 

輸出:

[{'hop': 2, 'source': 1, 'volume': 150.5}, 
{'hop': 2, 'source': 2, 'volume': 200.7}, 
{'destination': 3, 'hop': 2, 'volume': 100.5}, 
{'destination': 4, 'hop': 2, 'volume': 250.7}] 

以上將在運行爲O(n)時間,所以它應具有數百萬流動的工作前提是你有足夠的內存。

+0

我喜歡你的方法,但我的音量實際上是一個浮動。所以不容易計算我猜... 任何想法如何解決? – mxzwrnz

+0

@mxzwrnz解決了這個問題,出於某種原因,我讀取了像音量一樣的輸入,然後我將其轉換爲int以便我可以對其進行求和。刪除不必要的代碼,它工作正常。 – niemmi

0

僞算法:

  1. 創建一個空的結果列表/設置/字典
  2. 遍歷德流列表
  3. 分裂爲每個這些2個鏈接的每個單流入2個鏈接
  4. 測試它們是否已經在結果列表中(基於2個節點)。
  5. 如果不是:添加它們。如果是:升級已經在列表中的音量。
+0

這就是我想到的。 但我的主要問題是,如何有效地完成第4步。除了每次循環播放結果列表,我怎樣才能檢查? – mxzwrnz

+0

使用'in'語句。例如:[(2,3),(1,2)]'中的(1,2)將給出'True'。 – Elmex80s

+0

但我不能這樣比較,因爲一個元組將包含源和tagert,但也可能有不同的鏈接到鏈接(並需要總結)的音量。 – mxzwrnz