Python intersect two list with condition -


is one-liner best way (without error , efficient) merging (doing intersection) of 2 lists if condition met?

res = [val val in list_1 if val in list_2 , condition[val] == true] 

i.e.

list_1 = [2 4 6 8 10] list_2 = [1 2 3 4 5 8 9] condition = {2:true, 4:false, 6:false, 8:true, 10:true} 

should return res = [2 8]. dictionary condition has same keys elements in list_1.

how should change code if instead of 2 lists had sets?

finally, note simplified case produced larger example cannot check visually. make sure solution valid in general , not posted example.

this valid test case.

however, isn't valid if val isn't guaranteed in condition.

if that's possibility, should either put try:/except: around check (which mean abstracting out explicit loop statement or separate function), or use condition.get(val, false) (assuming want treat "not in condition" falsey).

if isn't possibility, it's better leave code as-is; way, if "impossible" data, you'll exception instead of incorrect answer.


meanwhile, == true comparisons not idiomatic , not idea. pep 8 says:

don't compare boolean values true or false using ==.

of course guideline; there cases explicitly want make sure true, not truthy, in case need use == true or is true (the former accepts other numeric 1 values, latter doesn't). if don't have reason so, don't it.


also, say, "this simplified case produced larger example…" don't know how large "larger" is, code pretty inefficient if list_2 big enough.

you're checking each element of list_1 against every element of list_2, 1 one. so, if there are, say, 1000 entries in each list, that's 1000000 comparisons.

if instead convert list_2 set, you're doing set lookup each element of list 1, it's 1000 hashes , 1000 comparisons, not 1000000 comparisons.

you write as:

set_2 = set(list_2) res = [val val in list_1 if val in set_2 , condition[val]] 

you can simplify things in various ways. these won't affect performance, improve readability , semantic reasonability. in particular, ojy says, can combine 2 conditions 1 using set intersection, set comprehension, or both. example:

set_2 = set(list_2) & {k k, v in condition.items() if v} res = [val val in list_1 if val in set_2] 

you can take further using set intersection:

res = set(list_1) & set(list_2) & {k k, v in condition.items() if v} 

however, 1 changes semantics: discards duplicate values in list_1, , throws away order. if acceptable, it's idea it, make obvious duplicates impossible , order irrelevant. if not, don't this.


finally, it's worth asking whether you're using wrong data structures in first place. can build list_2 set instead of list in first place? or list_1? can build conditions set of true keys instead of dict mapping true , false?


Comments

Popular posts from this blog

c++ - QTextObjectInterface with Qml TextEdit (QQuickTextEdit) -

javascript - angular ng-required radio button not toggling required off in firefox 33, OK in chrome -

xcode - Swift Playground - Files are not readable -