简体   繁体   English

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

[英]efficient way to insert elements into a dictionary

Is there a simpler way to write this code?有没有更简单的方法来编写这段代码?

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)

You could use a defaultdict and simplify the code to您可以使用defaultdict并将代码简化为

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

Note that in this case the dictionary would need to be defined as:请注意,在这种情况下,字典需要定义为:

self.dict = defaultdict(list)

Or, if you want to associate a set to your keys you could just change it to defaultdict(set) and use:或者,如果您想将一个集合与您的键相关联,您可以将其更改为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)

Without any changes to the types you use, you can also just do the following in one line:无需对您使用的类型进行任何更改,您也可以在一行中执行以下操作:

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

Or, when using sets:或者,当使用集合时:

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

Here's an exercise in the problem showing use of exception handling and limited recursion - this may be the most efficient way to do it.这是问题中的一个练习,展示了异常处理和有限递归的使用——这可能是最有效的方法。 Although it 'looks' like the code is larger than other solutions, it compiles down into fewer instructions than the others:尽管“看起来”代码比其他解决方案大,但它编译成的指令比其他解决方案少:

>>> 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]}

I believe this will have the fastest performance assuming most of your data is lists of numbers with only occasional single digits.我相信这将具有最快的性能,假设您的大部分数据是只有偶尔个位数的数字列表。 And that the keys don't vary wildly.并且键不会变化很大。 The single line self.dict[k].extend(v) should be executed without exceptions the majority of accesses to the object.单行self.dict[k].extend(v)应该毫无例外地执行大多数对对象的访问。 It incurs no extra cost checking types and testing conditions.它不会产生额外的成本检查类型和测试条件。 Even if single digits were frequent, branching to add them incurs about the same cost as type checking - except this implementation isn't forced to type check every time something is added.即使单个数字很频繁,分支添加它们也会产生与类型检查相同的成本——除了这种实现不会在每次添加内容时强制进行类型检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM