通过迭代返回Python中两个元素的元组的函数来创建两个字典

时间:2019-07-02 09:59:26

标签: python dictionary-comprehension

我想通过字典理解同时在python中创建两个字典。这两个词典共享相同的键集,但每个键具有不同的值。因此,我使用一个函数返回两个值的元组,并希望通过字典理解可以同时创建这两个字典。

说,我有一个功能

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)将在每次迭代中被调用两次,从而减慢代码速度。正确的方法是什么?

5 个答案:

答案 0 :(得分:1)

for key in list_of_keys:
   dict_of_a[key],dict_of_b[key] = my_func(key)

答案 1 :(得分:0)

  

my_func(key)在每次迭代中都会被调用两次,从而降低代码速度

不用担心。除非您需要进行数以千计的迭代,并且脚本花费了不合理的长时间,否则您不必担心优化收益微不足道。

那就是说,我会用这样的东西:

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

答案 2 :(得分:0)

您不能在一个词典理解中创建两个词典。 如果您的主要目标是只调用一次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

答案 3 :(得分:0)

顺序切片:

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

答案 4 :(得分:0)

常规循环可能是最好的方法。如果您想玩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))一次提取一则字典,并返回func返回值的匹配元素;
  • {**d, x: v}用当前值更新字典。

由于不易维护,因此我不建议您使用这种代码。