Python 循环 vs 列表推导 vs map的副作用(即不使用返回值)
简而言之:哪个更好?
1.- [r.update(r.pop('some_key')) for r in res if r.get('some_key')]
2.- map(lambda r: r.update(r.pop('some_key') if r.get('some_key') else []), res)
3.- map(lambda r: r.update(r.pop('some_key')), filter(lambda r: r.get('some_key'), res))
4.- for r in res:
if r.get('some_key'):
for element in r['some_key']:
r[element] = r['some_key'][element]
del r['some_key']
5.- Insert your own approach here
注意:这段代码不是用在生产环境中的,而是用在测试中,所以我更关心代码的可读性和可维护性,而不是性能。不过,我也想知道,如果这是生产代码,关于哪个更好的选择(在性能和可读性之间的权衡)是否会有所不同。因为'some_key'的元素数量很少,如果这有影响的话。
背景:我读过一篇文章,讨论了Python的列表推导和map函数,其中的一个被接受的回答说:
[...] 在其他情况下,列表推导可能更快,而且大多数(不是全部)Python爱好者认为它们更直接、更清晰 [...].
然而,另一个问题的被接受回答仅仅为了副作用使用列表推导是否符合Python风格?中提到:
这样做非常不符合Python风格 [仅仅为了副作用使用列表推导,忽略返回值],任何有经验的Python爱好者都会对此表示不满。中间生成的列表在创建后就被丢弃了,而且它可能会非常非常大,因此创建它的成本可能很高。
附言:我已经有了自己认为哪个更好的看法,但我的一个同事不同意。这就是我询问的原因。
2 个回答
2
1.- [r.update(r.pop('some_key')) for r in res if r.get('some_key')]
使用列表推导式来产生副作用是不推荐的。因为它会创建一个列表,但最后这个列表会被丢弃。
2.- map(lambda r: r.update(r.pop('some_key') if r.get('some_key') else []), res)
和1
差不多,只是这个在Python 3.X中会出问题。
3.- map(lambda r: r.update(r.pop('some_key')), filter(lambda r: r.get('some_key'), res))
比3
更糟。除了使用map
并依赖副作用外,你还增加了函数调用的开销。
4.- for r in res:
if r.get('some_key'):
for element in r['some_key']:
r[element] = r['some_key'][element]
del r['some_key']
这个比其他的都好。
- 没有生成不必要的列表,这些列表最后会被丢掉。
- 在Python 3.x中可以正常工作。
- 没有额外的函数调用开销。
5.- 在这里插入你自己的方法。
for r in res:
if 'some_key' in r:
r.update(r['some_key'])
del r['some_key']
2
我觉得这个对Abhijit回答的变种,同时也是我第四点的变种,是最好的选择。
for r in res:
r.update(r.pop('some_key', {}))
- 拥有普通
for
循环的所有优点 - 容易理解
- 只需要两行代码
- 不需要
if
条件语句