簡體   English   中英

將元素插入字典的有效方法

[英]efficient way to insert elements into a dictionary

有沒有更簡單的方法來編寫這段代碼?

def insert(k, v)  # v can either be a single number or a list of numbers, and k may or may not exist in self.dict
  if k in self.dict:
    if isinstance(v, list):
      for e in v:
        self.dict[k].add(e)
    else:
      self.dict[k].add(v)
  else:
    self.dict[k] = {}
    if isinstance(v, list):
      for e in v:
        self.dict[k].add(e)
    else:
      self.dict[k].add(v)

您可以使用defaultdict並將代碼簡化為

def insert(self, k, v): 
   if isinstance(v, list):
      self.dict[k]+=v
   else:
      self.dict[k].append(v)

請注意,在這種情況下,字典需要定義為:

self.dict = defaultdict(list)

或者,如果您想將一個集合與您的鍵相關聯,您可以將其更改為defaultdict(set)並使用:

def insert(self, k, v): 
   if isinstance(v, list):
      self.dict[k]|=set(v)
   else:
      self.dict[k].add(v)
def insert(k, v): entries = self.dict.setdefault(k, set()) if isinstance(v, list): entries.update(v) else: entries.add(v)

無需對您使用的類型進行任何更改,您也可以在一行中執行以下操作:

def insert(k, v): 
    d.setdefault(k, []).extend(v if isinstance(v, list) else [v])

或者,當使用集合時:

def insert(k, v): 
    d.setdefault(k, set()).update(v if isinstance(v, list) else [v])

這是問題中的一個練習,展示了異常處理和有限遞歸的使用——這可能是最有效的方法。 盡管“看起來”代碼比其他解決方案大,但它編譯成的指令比其他解決方案少:

>>> class Foo:
...     def __init__(self):
...         self.dict = {}
... 
...     def insert(self, k, v):
...         try:
...             self.dict[k].extend(v)  # <-- majority of accesses 
...                                     #     only execute this one line.
...         except KeyError:
...             self.dict[k] = []
...             self.insert(k, v)
...         except TypeError:
...             self.dict[k].extend([v])
...             
>>> f = Foo()
>>> f.insert('bob', 1)
>>> f.dict
{'bob': [1]}
>>> f.insert('bob', [3, 4])
>>> f.dict
{'bob': [1, 3, 4]}

我相信這將具有最快的性能,假設您的大部分數據是只有偶爾個位數的數字列表。 並且鍵不會變化很大。 單行self.dict[k].extend(v)應該毫無例外地執行大多數對對象的訪問。 它不會產生額外的成本檢查類型和測試條件。 即使單個數字很頻繁,分支添加它們也會產生與類型檢查相同的成本——除了這種實現不會在每次添加內容時強制進行類型檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM