是否有更简单的方法来编写此代码?
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)
应该毫无例外地执行对对象的大多数访问。检查类型和测试条件不会产生额外的成本。即使个位数很频繁,添加它们的分支也会产生与类型检查大致相同的成本——只是这种实现并不是每次添加东西都必须进行类型检查。