以最佳方式从字典中删除所有值

2024-05-29 06:19:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典,像:

z = {'d': '2018', 'uc': '609', 'bc': 'HSBC', 'ab': 'FICCL', .... }

它有57个键值对。我想保留键,但删除值并使它们像“”一样成为空字符串。我尝试了以下代码:

for k,v in z.items():
    z[k] = ""

我得到了期望的输出,比如:

z = {'d': '', 'uc': '', 'bc': '', 'ab': '', .... }

我想知道这是否是一次删除字典中所有值的最简单方法。还有别的办法吗?是否有任何内置函数来执行此操作?有没有没有一条没有环的班轮?你知道吗


Tags: 方法字符串代码infor字典abitems
3条回答

如果您需要就地更新dictionary,那么您必须对键进行迭代,因此您的方法是一种很好且可读的方法。它也比其他方法更新你的字典,甚至用相同的键创建一个新的字典快!你知道吗

您可以放弃items()调用,因为您对值不感兴趣。只需直接在字典上循环即可获取关键字:

for k in z:
    z[k] = ""

另一种方法是使用^{}创建一个新的空字典。要更新现有dict就地(以便同一词典的其他引用可以看到更改),可以调用z.update()传入新词典:

# set all values to an empty string, in place
z.update(dict.fromkeys(z, ""))

缺点是您可能需要添加注释来解释该行应该实现的功能。它的速度也比较慢,因为创建新对象只是为了更新现有对象。此外,您还需要谨慎地使用dict.fromkeys(),因为第二个参数是对所有键重用的单个值。如果要使用列表之类的可变值,这一点很重要。如果您只需要一个新的字典,那么您可以与z.update()进行协商,并将dict.fromkeys()结果直接分配给z。你知道吗

假设您需要进行适当的更新,快速比较性能差异:

>>> from timeit import Timer
>>> testdict = {i: i for i in range(10 ** 6)}
>>> def explicit_loop(d):
...     d = d.copy()
...     for k in d:
...         d[k] = ""
...
>>> def dict_fromkeys(d):
...     d = d.copy()
...     d.update(dict.fromkeys(d, ""))
...
>>> def base_copy(d):
...     d = d.copy()
...
>>> count, total = Timer("f(t)", "from __main__ import base_copy as f, testdict as t").autorange()
>>> base_copy_time = total / count
>>> for f in (explicit_loop, dict_fromkeys):
...     count, total = Timer("f(t)", f"from __main__ import {f.__name__} as f, testdict as t").autorange()
...     print(f"{f.__name__:>15}: {((total / count) - base_copy_time) * 1000:.2f} milliseconds")
...
  explicit_loop: 43.15 milliseconds
  dict_fromkeys: 68.66 milliseconds

请注意,为了方便进行准确的测试,每次都需要复制输入字典,这就是为什么要使用base_copy测试来调整计时。你知道吗

您可以看到z上的显式循环显然是赢家。但是,即使您不需要就地更新字典,使用dict.fromkeys()也比就地更新z慢!你知道吗

就地更新不必动态调整字典大小以适应任意数量的键,也不需要创建新对象:

>>> def dict_fromkeys_no_update(d):
...     d = d.copy()  # to keep comparisons fair, copy only needed for the loop case
...     d = dict.fromkeys(d, "")
...
>>> for f in (explicit_loop, dict_fromkeys_no_update):
...     count, total = Timer("f(t)", f"from __main__ import {f.__name__} as f, testdict as t").autorange()
...     print(f"{f.__name__:>25}: {((total / count) - base_copy_time) * 1000:.2f} milliseconds")
...
            explicit_loop: 41.27 milliseconds
  dict_fromkeys_no_update: 54.78 milliseconds

因此,无论您是否需要一个新的字典或一个就地更新,只要在现有字典键上进行一个简单的Python循环,就是无可争议的赢家。你知道吗

您不需要.items(),因此您的代码可以简化:

for k in z:
    z[k] = ""

我不认为有一个单一的班轮做同样的事情,是同样的效率/可读性。在这里使用循环是完全好的(除非有特定的原因需要一个函数调用)。你知道吗

校验方法fromkeys 那就是z = z.fromkeys(z, '') 希望有帮助

相关问题 更多 >

    热门问题