7

有没有更简洁的方法通过谓词将列表分成两个列表?

errors, okays = [], []
for r in results:
    if success_condition(r):
        okays.append(r)
    else:
        errors.append(r)

我知道这可以变成一个丑陋的单线使用reduce; 这不是我要找的。

更新:每个元素只计算success_condition一次是可取的。

4

5 回答 5

6

也许

for r in results:
    (okays if success_condition(r) else errors).append(r)

但这看起来/感觉不是很 Pythonic。


不直接相关,但如果要寻找效率,缓存方法查找会更好:

okays_append = okays.append
errors_append = errors.append

for r in results:
    (okays_append if success_condition(r) else errors_append)(r)

这更不像 Pythonic。

于 2012-08-15T18:37:16.237 回答
4

怎么样

errors = [ r for r in results if not success_condition(r)]
okays = [ r for r in results if success_condition(r)]

或者

bools = [ success_condition(r) for r in results ] 

如果success_condition是一个昂贵的电话,然后替换上面(通过zip或)。enumerate

于 2012-08-15T18:33:35.987 回答
4
errors, okays = [], []
for r in results:
    (errors, okays)[success_condition(r)].append(r)
于 2012-08-15T19:38:54.210 回答
1

使用具有副作用的生成器表达式或列表推导。(只是为了使其看起来简洁):

>>> errors, okays = [], []
>>> [okays.append(r) if success_condition(r) else errors.append(r)  for r in results]

使用生成器表达式:

>>> errors, okays = [], []
>>> list(okays.append(r) if success_condition(r) else errors.append(r)  for r in results)
于 2012-08-15T18:43:03.427 回答
0

filter功能呢?

okays = filter(success_condition, results)
errors = filter(lambda (x): not success_condition(x), results)
于 2012-08-15T18:36:19.667 回答