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)