Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 以最佳方式从字典中删除所有值_Python_Python 3.x_Dictionary - Fatal编程技术网

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

Python 以最佳方式从字典中删除所有值,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我有一本像这样的字典: z = {'d': '2018', 'uc': '609', 'bc': 'HSBC', 'ab': 'FICCL', .... } 它有57个键值对。我希望保留键,但删除值并使它们成为空字符串,如“”。我尝试了以下代码: for k,v in z.items(): z[k] = "" 我得到了所需的输出,如: z = {'d': '', 'uc': '', 'bc': '', 'ab': '', .... } 我想知道这是否是一次删除字典中所有值的最简单方

我有一本像这样的字典:

z = {'d': '2018', 'uc': '609', 'bc': 'HSBC', 'ab': 'FICCL', .... }
它有57个键值对。我希望保留键,但删除值并使它们成为空字符串,如“”。我尝试了以下代码:

for k,v in z.items():
    z[k] = ""
我得到了所需的输出,如:

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

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

您可以使用
fromkeys
从键列表创建字典,并指定“空”值应该是什么

z = dict.fromkeys(z.keys(), "")
empty_dict = dict.fromkeys(original_dict.keys(), '')

您可以使用
fromkeys
从键列表创建字典,并指定“空”值应该是什么

empty_dict = dict.fromkeys(original_dict.keys(), '')

签出方法
fromkeys
这将是
z=z.fromkeys(z',)

希望对您有所帮助

签出方法
fromkeys
这将是
z=z.fromkeys(z',)

希望这对您有所帮助,因为您不需要
.items()
,所以您的代码可以简化:

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

我不认为有一行程序可以做同样的事情,并且同样有效/可读。在这里使用循环是完全可以的(除非您需要单个函数调用有特定的原因)。

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

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

我不认为有一行程序可以做同样的事情,并且同样有效/可读。在这里使用循环是完全可以的(除非有特定的原因需要一个函数调用)。

如果需要在适当的位置更新字典,则必须迭代键,因此您的方法是一种良好且可读的方法。它也比其他更新字典的方法更快,甚至比创建具有相同键的新字典更快

您可以放弃
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\u 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] = ""
另一种方法是使用创建一个新的空字典。要就地更新现有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\u 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循环都是无可争议的赢家。

总结和计时各种已发布的答案,它们在运行时看起来大致相同

我首先创建一个相对较大的
dict

src = {str(i):i for i in range(1_000_000)}
使用
dict.fromkeys

dict.fromkeys(src.keys(), '')
取183 ms±11.7 ms。注意,穆罕默德的
z.fromkeys(z…
也在做同样的事情

dict
理解:

{k:'' for k in src.keys()}
助教