Split predicate lists

Is there a more concise way to split a list into two lists by a predicate?

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

I understand that this can be turned into an ugly single line with reduce ; this is not what i'm looking for.

Update: calculating success_condition is only possible once for each element.

+6
source share
5 answers

Can

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

But it does not look / feel very Pythonic.


Not directly relevant, but if you're looking for efficiency, caching search methods would be better:

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

What is even less Pythonic.

+5
source

What about

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

or

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

and then replace the above (via zip or enumerate ) if success_condition is an expensive call.

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

Use a generator expression or a list comprehension with a side effect (just to make it look concise):

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

with generator expression:

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

What about the filter function?

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

Source: https://habr.com/ru/post/922973/


All Articles