enhancerlist=[[5,8],[10,11]]
TFlist=[[6,7],[24,56]]
I have two lists of lists. I am trying to isolate the sublists in my 'TFlist' that don't fit in the range of ANY of the sublists of enhancerlist (by range: TFlist sublist range fits inside of enhancerlist sublist range). SO for example, TFlist[1] will not occur in the range of any sublists in enhancerlist (whereas TFlist [6,7] fits inside the range of [5,8]) , so I want this as output:
TF_notinrange=[24,56]
the problem with a nested for loop like this:
while TFlist:
TF=TFlist.pop()
for j in enhancerlist:
if ((TF[0]>= j[0]) and (TF[1]<= j[1])):
continue
else:
TF_notinrange.append(TF)
is that I get this as output: [[24, 56], [3, 4]]
the if statement is checking one sublist in enhancerlist at a time and so will append TF even if, later on, there is a sublist it is in the range of.
Could I somehow do a while loop with the condition? although it seems like I still have the issue of a nested loop appending things incorrectly ?
CodePudding user response:
You can use a nested for loop to solve this problem.
Currently you are appending TF
to TF_notinrange
if it does not fit in the range of the current sublist in enhancerlist
. You should instead check if TF
fits in the range of any of the sublists in enhancerlist
.
Here is one way you can do this:
enhancerlist = [[5,8],[10,11]]
TFlist = [[6,7],[24,56]]
TF_notinrange = []
for TF in TFlist:
in_range = False
for j in enhancerlist:
if ((TF[0]>= j[0]) and (TF[1]<= j[1])):
in_range = True
break
if not in_range:
TF_notinrange.append(TF)
print(TF_notinrange)
This should output [[24, 56]]
Hope this helps!
CodePudding user response:
Alternative is to use a list comprehension:
TF_notinrange = [tf for tf in TFlist
if all(tf[0] < istart or tf[1] > iend
for istart, iend in enhancerlist)]
print(TF_notinrange)
>>> TF_notinrange
Explanation
Take ranges of TFlist which are not contained in any ranges of enhancerlist
CodePudding user response:
You can use chained comparisons along with the less-common for-else
block where the else
clause triggers only if the for
loop was not broken out of prematurely to achieve this:
non_overlapping = []
for tf_a, tf_b in TFlist:
for enhancer_a, enhancer_b in enhancerlist:
if enhancer_a <= tf_a < tf_b <= enhancer_b:
break
else:
non_overlapping.append([tf_a, tf_b])
Note that this assumes that all pairs are already sorted and that no pair comprises a range of length zero (e.g., (2, 2)
).