通过迭代 returns Python 中两个元素的元组的函数来创建两个字典
Create two dictionaries by iterating through a function that returns a tuple of two elements in Python
我想通过字典推导同时在python 中创建两个字典。两个字典共享相同的键集,但每个键的值不同。因此,我用一个函数来return一个有两个值的元组,希望字典理解可以同时创建这两个字典。
说,我有一个功能
def my_func(foo):
blablabla...
return a, b
然后我将通过
创建两个词典
dict_of_a, dict_of_b = ({key:my_func(key)[0]}, {key:my_func(key)[1]} for key in list_of_keys)
有没有更好的代码可以改进呢?在我看来,my_func(key) 将在每次迭代中被调用两次,从而减慢代码速度。正确的做法是什么?
my_func(key) will be called twice in each iteration, slowing down the code
别担心。除非您需要执行 thousands/millions 次迭代并且脚本需要很长时间才能完成,否则您不应该担心微不足道的优化收益。
也就是说,我会使用这样的东西:
if __name__ == '__main__':
def my_func(k):
return f'a{k}', f'b{k}'
keys = ['x', 'y', 'z']
results = (my_func(k) for k in keys)
grouped_values = zip(*results)
da, db = [dict(zip(keys, v)) for v in grouped_values]
print(da)
print(db)
# Output:
# {'x': 'ax', 'y': 'ay', 'z': 'az'}
# {'x': 'bx', 'y': 'by', 'z': 'bz'}
您不能在一个听写理解中创建两个听写。
如果您的主要目标是只调用 my_func
一次来创建两个字典,请为此使用一个函数:
def mkdicts(keys):
dict_of_a = {}
dict_of_b = {}
for key in keys:
dict_of_a[key], dict_of_b[key] = my_func(key)
return dict_of_a, dict_of_b
for key in list_of_keys:
dict_of_a[key],dict_of_b[key] = my_func(key)
有序切片:
def myfunc(k):
return k + '0', k + '1'
list_of_keys = ['a', 'b', 'c']
groups = [(k,v) for k in list_of_keys for v in myfunc(k)]
dict_of_a, dict_of_b = dict(groups[::2]), dict(groups[1::2])
print(dict_of_a) # {'a': 'a0', 'b': 'b0', 'c': 'c0'}
print(dict_of_b) # {'a': 'a1', 'b': 'b1', 'c': 'c1'}
常规循环可能是最好的方法。如果你想玩functools
,你可以这样写:
>>> def func(foo): return foo[0], foo[1:]
...
>>> L = ['a', 'ab', 'abc']
>>> functools.reduce(lambda acc, x: tuple({**d, x: v} for d, v in zip(acc, func(x))), L, ({}, {}))
({'a': 'a', 'ab': 'a', 'abc': 'a'}, {'a': '', 'ab': 'b', 'abc': 'bc'})
函数 reduce
是一个折叠:它接受当前累加器(这里是正在构建的字典)和来自 L
的下一个值:
d, v in zip(acc, func(x))
一次提取一个dicts和func
的return值的匹配元素;
{**d, x: v}
用当前值更新字典。
我不推荐这种代码,因为它很难维护。
我想通过字典推导同时在python 中创建两个字典。两个字典共享相同的键集,但每个键的值不同。因此,我用一个函数来return一个有两个值的元组,希望字典理解可以同时创建这两个字典。
说,我有一个功能
def my_func(foo):
blablabla...
return a, b
然后我将通过
创建两个词典dict_of_a, dict_of_b = ({key:my_func(key)[0]}, {key:my_func(key)[1]} for key in list_of_keys)
有没有更好的代码可以改进呢?在我看来,my_func(key) 将在每次迭代中被调用两次,从而减慢代码速度。正确的做法是什么?
my_func(key) will be called twice in each iteration, slowing down the code
别担心。除非您需要执行 thousands/millions 次迭代并且脚本需要很长时间才能完成,否则您不应该担心微不足道的优化收益。
也就是说,我会使用这样的东西:
if __name__ == '__main__':
def my_func(k):
return f'a{k}', f'b{k}'
keys = ['x', 'y', 'z']
results = (my_func(k) for k in keys)
grouped_values = zip(*results)
da, db = [dict(zip(keys, v)) for v in grouped_values]
print(da)
print(db)
# Output:
# {'x': 'ax', 'y': 'ay', 'z': 'az'}
# {'x': 'bx', 'y': 'by', 'z': 'bz'}
您不能在一个听写理解中创建两个听写。
如果您的主要目标是只调用 my_func
一次来创建两个字典,请为此使用一个函数:
def mkdicts(keys):
dict_of_a = {}
dict_of_b = {}
for key in keys:
dict_of_a[key], dict_of_b[key] = my_func(key)
return dict_of_a, dict_of_b
for key in list_of_keys:
dict_of_a[key],dict_of_b[key] = my_func(key)
有序切片:
def myfunc(k):
return k + '0', k + '1'
list_of_keys = ['a', 'b', 'c']
groups = [(k,v) for k in list_of_keys for v in myfunc(k)]
dict_of_a, dict_of_b = dict(groups[::2]), dict(groups[1::2])
print(dict_of_a) # {'a': 'a0', 'b': 'b0', 'c': 'c0'}
print(dict_of_b) # {'a': 'a1', 'b': 'b1', 'c': 'c1'}
常规循环可能是最好的方法。如果你想玩functools
,你可以这样写:
>>> def func(foo): return foo[0], foo[1:]
...
>>> L = ['a', 'ab', 'abc']
>>> functools.reduce(lambda acc, x: tuple({**d, x: v} for d, v in zip(acc, func(x))), L, ({}, {}))
({'a': 'a', 'ab': 'a', 'abc': 'a'}, {'a': '', 'ab': 'b', 'abc': 'bc'})
函数 reduce
是一个折叠:它接受当前累加器(这里是正在构建的字典)和来自 L
的下一个值:
d, v in zip(acc, func(x))
一次提取一个dicts和func
的return值的匹配元素;{**d, x: v}
用当前值更新字典。
我不推荐这种代码,因为它很难维护。