Menghapus Duplikat Dari Kamus

Saya memiliki struktur data kamus Python 2.7 berikut ini (saya tidak mengontrol sumber data - berasal dari sistem lain sebagaimana adanya):

{112762853378:
   {\an8}; dst>: ['10.121.4.136'],
    'src': ['1.2.3.4'],
    'alias': ['www.example.com']
   },
 112762853385:
   {{#39;dst': ['10.121.4.136'],
    'src': ['1.2.3.4'],
    'alias': ['www.example.com']
   },
 112760496444:
   {'dst': ['10.121.4.136'],
    'src': ['1.2.3.4']
   },
 112760496502:
   {'dst': ['10.122.195.34'],
    'src': ['4.3.2.1']
   },
 112765083670: ...
}

Kunci kamus akan selalu unik. Dst, src, dan alias dapat berupa duplikat. Semua record akan selalu memiliki dst dan src tetapi tidak setiap record akan selalu memiliki alias seperti yang terlihat pada record ketiga.

Dalam contoh data, salah satu dari dua record pertama akan dihapus (tidak masalah bagi saya yang mana). Record ketiga akan dianggap unik karena meskipun dst dan src sama, namun tidak ada alias.

Tujuan saya adalah menghapus semua record di mana dst, src, dan alias semuanya telah diduplikasi - terlepas dari kuncinya.

Bagaimana cara rookie ini menyelesaikannya?

Juga, pemahaman saya yang terbatas tentang Python menginterpretasikan struktur data sebagai kamus dengan nilai-nilai yang disimpan dalam kamus... sebuah diktat dari diktat, apakah ini benar?

Larutan

Anda bisa memeriksa setiap item (pasangan nilai kunci) dalam kamus dan menambahkannya ke dalam kamus hasil jika nilainya belum ada dalam kamus hasil.

input_raw = {112762853378: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4'], 
    'alias': ['www.example.com']
   },
 112762853385: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4'], 
    'alias': ['www.example.com']
   },
 112760496444: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4']
   },
 112760496502: 
   {'dst': ['10.122.195.34'], 
    'src': ['4.3.2.1']
   }
}

result = {}

for key,value in input_raw.items():
    if value not in result.values():
        result[key] = value

print result
Komentar (10)

Salah satu pendekatan sederhana adalah membuat kamus terbalik dengan menggunakan penggabungan data string di setiap kamus bagian dalam sebagai kunci. Jadi, katakanlah Anda memiliki data di atas dalam sebuah kamus, d:

>>> import collections
>>> reverse_d = collections.defaultdict(list)
>>> for key, inner_d in d.iteritems():
...     key_str = ''.join(inner_d[k][0] for k in ['dst', 'src', 'alias'] if k in inner_d)
...     reverse_d[key_str].append(key)
... 
>>> duplicates = [keys for key_str, keys in reverse_d.iteritems() if len(keys) > 1]
>>> duplicates
[[112762853385, 112762853378]]

Jika anda tidak menginginkan daftar duplikat atau semacamnya, tetapi hanya ingin membuat diktat tanpa duplikat, anda bisa menggunakan kamus biasa, bukan defaultdict dan membalikkannya seperti itu:

>>> for key, inner_d in d.iteritems():
...     key_str = ''.join(inner_d[k][0] for k in ['dst', 'src', 'alias'] if k in inner_d)
...     reverse_d[key_str] = key
>>> new_d = dict((val, d[val]) for val in reverse_d.itervalues())
Komentar (1)

Karena cara untuk menemukan keunikan dalam korespondensi adalah dengan menggunakan kamus, dengan nilai unik yang diinginkan sebagai kuncinya, cara yang harus ditempuh adalah dengan membuat diktat terbalik, di mana nilai Anda disusun sebagai kunci - kemudian buat ulang "de-reversed &" kamus menggunakan hasil antara.

dct = {112762853378: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4'], 
    'alias': ['www.example.com']
   },
 112762853385: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4'], 
    'alias': ['www.example.com']
   },
 112760496444: 
   {'dst': ['10.121.4.136'], 
    'src': ['1.2.3.4']
   },
 112760496502: 
   {'dst': ['10.122.195.34'], 
    'src': ['4.3.2.1']
   },
   }

def remove_dups (dct):
    reversed_dct = {}
    for key, val in dct.items():
        new_key = tuple(val["dst"]) + tuple(val["src"]) + (tuple(val["alias"]) if "alias" in val else (None,) ) 
        reversed_dct[new_key] = key
    result_dct = {}
    for key, val in reversed_dct.items():
        result_dct[val] = dct[val]
    return result_dct

result = remove_dups(dct)
Komentar (1)