Python 按谓词拆分列表

Python 按谓词拆分列表,python,Python,有没有更简洁的方法通过谓词将列表拆分为两个列表 errors, okays = [], [] for r in results: if success_condition(r): okays.append(r) else: errors.append(r) 我知道,使用reduce,这可能会变成一个丑陋的单行程序;这不是我要找的 更新:每个元素只需计算一次成功条件。如何 errors = [ r for r in results if not s

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

errors, okays = [], []
for r in results:
    if success_condition(r):
        okays.append(r)
    else:
        errors.append(r)
我知道,使用
reduce
,这可能会变成一个丑陋的单行程序;这不是我要找的

更新:每个元素只需计算一次成功条件。

如何

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


然后,如果成功条件是一个代价高昂的调用,则替换上面的内容(通过
zip
enumerate
)。

那么
过滤器
功能呢

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

但这看起来/感觉不太像蟒蛇


不直接相关,但如果希望提高效率,则缓存方法查找会更好:

okays_append = okays.append
errors_append = errors.append

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

这就更不符合Pythonic了。

使用生成器表达式或列表理解会产生副作用(只是为了让它看起来简洁):

使用生成器表达式:

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

但是为了得到好的元素,你需要再次过滤——有效地检查每个元素两次(这可能很昂贵)。是的,这是真的,但他要求简洁,不efficiency@dfb我删除了它,因为它实际上并不更简洁。我想当你把
bools
zip
结合起来的时候,它不会很简洁anymore@gnibbler-真的吗?如果r[1]],则在zip(结果、布尔)中的r将变成
okays=[r[0]。不太糟糕。。。或者你是说它是3行而不是2行?你的代码很好。所有建议的解决方案都是循环和应用过滤函数两次。@PaoloMoretti:我同意你的第一句话,但你的第二句话是错误的——请参阅DBAPP的@PaoloMoretti和dfb的第二个建议。可能重复的我也同意@PaoloMoretti的第一句话,这是代码,没有问题。这些解决方案比你的没有任何优势这根本不起作用。尚未执行生成器表达式中的任何内容。您需要使用列表理解(或者以某种方式迭代生成器表达式,例如
[None for uu in if False]
)。@dbaupp我想只要
list()
就可以了。当然(这相当于列表理解)。但我的另一个建议是避免为列表分配一大块内存,然后立即将其丢弃。(虽然刚才做了一些快速测试表明我的技巧比普通的
list(…)
call,哈哈!)
any()
作为
列表更好。append
总是返回
False
它将贯穿整个过程该死的酷:)我想知道它是否通过了我们的代码审查,但无论如何。它应用谓词两次,这是不可取的。
okays_append = okays.append
errors_append = errors.append

for r in results:
    (okays_append if success_condition(r) else errors_append)(r)
>>> 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)
errors, okays = [], []
for r in results:
    (errors, okays)[success_condition(r)].append(r)