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
orfalse
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
Post a Comment