如何在字典推导式中单次调用函数提取键值对?
如何在字典推导式中单次调用函数生成键值对?
我有一个名为foo的函数,能从字符串生成键(key)和值(value)。我想在字典推导式中使用这个函数,但还没找到在单次迭代里提取多个值的方法。需要注意的是,foo函数可能执行成本很高、带有状态或者需要远程调用,所以每次迭代不能调用它超过一次。
示例代码:
def foo(s): # 模拟高成本函数的占位实现 return s[0], s[1:] print([foo(s) for s in ['abcd', 'efg', 'hi']]) print({foo(s) for s in ['abcd', 'efg', 'hi']}) print({foo(s)[0]: foo(s)[1] for s in ['abcd', 'efg', 'hi']})
输出:
[('a', 'bcd'), ('e', 'fg'), ('h', 'i')] # 列表推导式正常工作 {('a', 'bcd'), ('e', 'fg'), ('h', 'i')} # 集合推导式正常工作 {'a': 'bcd', 'e': 'fg', 'h': 'i'} # 得到了想要的字典结果,但函数被调用了两次
解决方案
方法1:利用dict()直接转换生成器结果
直接通过生成器表达式调用一次foo生成键值对元组,再传入dict()构造字典,每个元素仅调用一次foo:
def foo(s): return s[0], s[1:] data = ['abcd', 'efg', 'hi'] result = dict(foo(s) for s in data) print(result) # 输出: {'a': 'bcd', 'e': 'fg', 'h': 'i'}
方法2:在字典推导式中嵌套生成器表达式
如果更偏好字典推导式的写法,可以先通过生成器预先生成foo的返回结果,再在推导式内解包键值:
def foo(s): return s[0], s[1:] data = ['abcd', 'efg', 'hi'] result = {k: v for k, v in (foo(s) for s in data)} print(result) # 输出: {'a': 'bcd', 'e': 'fg', 'h': 'i'}
这两种方案都能保证每个s仅触发一次foo调用,完美解决重复调用的问题,同时得到预期的字典结果。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

