2017-08-22 103 views
0

我的第1套從數據庫中的數據是這樣的:在python中,如何刪除字典內的字典列表的重複值?

[ 
    {u'ip': u'13.82.28.61', u'scanid': 1000, u'port': 443}, 
    {u'ip': u'206.190.36.45', u'scanid': 1001, u'port': 80}, 
    {u'ip': u'98.139.180.149', u'scanid': 1001, u'port': 80}, 
    {u'ip': u'98.138.253.109', u'scanid': 1001, u'port': 80}, 
    {u'ip': u'91.198.174.192', u'scanid': 1002, u'port': 110}, 
    {u'ip': u'91.198.174.192', u'scanid': 1002, u'port': 31337} 
] 

我需要根據scanid數據,如:

{ 
    scanid : [{ip : [port1, port2 ...]}, {ip2 : [port3 ...]}], 
    scanid : [{ip3 : [port1, port2 ...]}, {ip4 : [port3 ...]}], 
    ... 
} 

這裏IP的一個scanid內不應重複。例如,

{ 
    1000: [{u'13.82.28.61': [443]}], 
    1001: [{u'206.190.36.45': [80]}, {u'98.139.180.149': [80]}, {u'98.138.253.109': [80]}], 
    1002: [{u'91.198.174.192': [110, 31337]}] 
} 

我嘗試下面的代碼:

d = defaultdict(list) 
dictionary_with_scanid = defaultdict(list) 
for rs in resultset: 
    scanid = rs['scanid'] 
    domain = rs['ip']  
    port = rs['port'] 
    d[domain].append(port) 
    dictionary_with_scanid[scanid].append({domain:d[domain]}) 

但我得到了重複數據scanid=1002

{ 
    1000: [{u'13.82.28.61': [443]}], 
    1001: [{u'206.190.36.45': [80]}, {u'98.139.180.149': [80]}, {u'98.138.253.109': [80]}], 
    1002: [{u'91.198.174.192': [110, 31337]}, {u'91.198.174.192': [110, 31337]}] 
} 

這是我的第二組數據,但scanid 1002有相同的重複數據:

1002: [{u'91.198.174.192': [110, 31337]}, {u'91.198.174.192': [110, 31337]}] 

我要低於這個數據不重複的特徵,無論是從第一組數據或第二組:

{ 
    1000: [{u'13.82.28.61': [443]}], 
    1001: [{u'206.190.36.45': [80]}, {u'98.139.180.149': [80]}, {u'98.138.253.109': [80]}], 
    1002: [{u'91.198.174.192': [110, 31337]}] 
} 
+3

如果每個scanid中的IP都應該是唯一的,那麼爲什麼不使用_single_字典而不是每個鍵都有一個鍵的字典列表呢? – tzaman

+0

如果你不能重複,那麼使用一組字典而不是一個字典列表 – AK47

+1

首先 - 如果你使它更通用,那麼更有可能得到你的問題的答案。您的問題與IP,端口或域無關。它是關於從嵌套字典中刪除重複項,爲什麼不編寫一個更簡單的例子,而不是用長值,變量的名稱等粘貼你的實際代碼? – Artur

回答

0

你嵌套太多,只是使用每個scanid一個字典。我使用setdefault在這裏,但你可以實現與defaultdict過類似的結果:

data = ... # your original data 
scans = {} 
for d in data: 
    scans.setdefault(d['scanid'], {}).setdefault(d['ip'], []).append(d['port']) 
print scans 

結果:

{1000: {u'13.82.28.61': [443]}, 
1001: {u'206.190.36.45': [80], 
     u'98.139.180.149': [80], 
     u'98.138.253.109': [80]}, 
1002: {u'91.198.174.192': [110, 31337]}} 

defaultdict設置是有點棘手,因爲你需要嵌套它們;你需要通過外部字典是構建內部一個自定義功能:

from collections import defaultdict 
scans = defaultdict(lambda: defaultdict(list)) 
for d in data: 
    scans[d['scanid']][d['ip']].append(d['port']) 
+0

這就是我想要的。非常感謝。你能否解釋一下代碼? –

+0

請使用defaultdict()發佈代碼。我用defaultdict()嘗試了很多,但無法做到。 –

+0

@ m.j加入;這是可以理解的,因爲它不是非常簡單。 – tzaman

0

我只想讓dictionary_with_scanid是dictionnaries的dictionnary避免IP重複:

d = defaultdict(list) 
dictionary_with_scanid = defaultdict(dict) # use dict instead of list 
for rs in resultset: 
    scanid = rs['scanid'] 
    domain = rs['ip'] 
    port = rs['port'] 
    d[domain].append(port) 
    # just use the previously updated d[domain] for dictionary_with_scanid[scanid] 
    dictionary_with_scanid[scanid][domain] = d[domain] 

它給預期:

pprint.pprint(dict(dictionary_with_scanid)) 
{1000: {'13.82.28.61': [443]}, 
1001: {'206.190.36.45': [80], '98.138.253.109': [80], '98.139.180.149': [80]}, 
1002: {'91.198.174.192': [110, 31337]}} 
相關問題