2017-09-11 144 views
0

我使用ipaddress模塊中的IPv4Network作爲字典中的鍵。這使我能夠快速查找重複數據,並注意其他一些數據。IPv4Network對象作爲字典中的鍵

但是,我很好奇,如果我可以堆疊IN語句並遠離O(n)處理。

from ipaddress import IPv4Network 
net1 = IPv4Network('10.10.10.0/24') 
net2 = IPv4Network('10.10.10.128/25') 
net3 = IPv4Network('10.10.10.0/24') 

dict1 = {net1: 'Winner!'} 
print(dict1.get(net3)) 
Winner! 

if net3 in dict1: 
    print('Yup') 
Yup 

# -------- This doesn't work, looking for way to accomplish it. 
if net2.network_address in dict1: 
    print('Wouldn't that be nice?) 
# --- Yes I can do this. 
for keys in dict1: 
    if net2.network_address in keys: 
     print(keys, 'I\'m inside you!') 

任何想法的聰明把戲?一種重構這種方式來利用一些內置的方法?

我想知道,如果

  1. 的關鍵在於存在重複(容易);和
  2. 如果IPv4Network作爲其中一個鍵被包含在內部。
+0

我對帖子進行了一些編輯,以糾正一些錯別字,並提高整體可讀性。在問題#2中,當你提到''network''時,我認爲你的意思是'IPv4Network',所以我在那裏改了它。如果您認爲我錯了,請隨時回滾該特定更改。 – ray

+1

我很累,並試圖解決幾件事情,你打我。當它告訴我你已更新它時,我正在進行編輯。 :) – Allen

回答

0

有沒有簡單的方法來做你想做的。 Python的字典查找使用散列來高效地查找字典密鑰的完全匹配。網絡的散列無法匹配它包含的所有地址。

您可能可以編寫自己的邏輯來高效地測試單個網絡或多個網絡的地址,但該代碼需要知道IP地址和網絡掩碼的工作方式。我會建議基於Trie的東西,並使用特殊的邏輯來支持主機位。

如果你只想寫在一行的循環代碼,你可以使用any

if any(net2.network_address in key for key in dict1): 
    ... 

但是,這不是比你當前的代碼更好了。這也不完全一樣,因爲在找到一場比賽之後短暫的any。因此,如果多個密鑰包含net2的地址,則any代碼將不會多次打印。您可以通過在代碼中調用print之後放置break來在原始循環代碼中複製any的行爲。