列表按谓词拆分

时间:2012-08-15 18:31:21

标签: python

是否有一种更简洁的方法可以通过谓词将列表拆分为两个列表?

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

据我所知,这可以使用reduce变成丑陋的单行;这不是我想要的。

更新:每个元素只需计算一次success_condition

5 个答案:

答案 0 :(得分: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。

答案 1 :(得分:3)

怎么样

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 ] 

然后替换上面(通过zipenumerate),如果success_condition是一个代价高昂的电话......

答案 2 :(得分:3)

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

答案 3 :(得分: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)

答案 4 :(得分:0)

filter功能怎么样?

okays = filter(success_condition, results)
errors = filter(lambda (x): not success_condition(x), results)