In a dictionary as follow:
example = {'Chr3' : [[1, 4], [5, 10], [13, 17]]}
How can I know in which list interval numbers 6 and 15 are located?
I can write a solution with a simple for
loop:
for key in example.keys():
for element in example[key]:
if element[0]<= 6 <= element[1] or element[0] <= 15 <= element[1]:
print element
But in my real problem, I don't have only two numbers but a list of numbers.
So, I was thinking if there is a more pythonic way of solving such a problem using special list or dictionary methods/functions?
EDIT: Because of down votes, I clarify that I know how to write the code using another loop on top for a list of numbers, I was wondering if there is a better solution to the same problem, a more efficient one!
Create a dictionary which maps any number from your list of numbers to the corresponding interval(s) in example['Chr3']
.
>>> {x:filter(lambda y: y[0] <= x <= y[1], example['Chr3']) for x in lst}
{6: [5, 10], 15: [13, 17]}
Use a function!
example = {'Chr3' : [[1, 4], [5, 10], [13, 17]]}
example_nums = [3, 6, 11, 15, 17]
def find_interval(dct, num):
for key, values in dct.items():
for left, right in values:
if left <= num <= right:
return [left, right]
print(find_interval(example, 6))
print(find_interval(example, 15))
# Now you can use the function to find the interval for each number
for num in example_nums:
print(num, find_interval(example, num))
[5, 10]
[13, 17]
3 [1, 4]
6 [5, 10]
11 None
15 [13, 17]
17 [13, 17]
Can you show more specific example of your list? I think your code though would work by incorporating the line for a loop over the list:
for x in my list:
for key in example.keys():
for element in example[key]:
if element[0]<= x <= element[1] or element[0] <= x <= element[1]:
print element
Your code looks for any match not multiple matches, you can use a list comp with any
from itertools import chain
pot = [6, 15]
print([[a, b] for a, b in chain(*example.values()) if any(a <= i <= b for i in pot)])
[[5, 10], [13, 17]]
If you just care about any match you only really need to check the min and max of the potential numbers:
pot = [6, 15,7,9,8]
from itertools import chain
mn,mx = min(pot), max(pot)
print([[a, b] for a, b in chain(*example.values()) if mn <= a <= mx or mn <= b <= mx])
[[5, 10], [13, 17]]
So you are now doing constant work to check a
and b
instead of linear.
Or using python3 you could use range and use in
which is an O(1)
operation in python3:
pot = [6, 15,7,9,8]
mn ,mx = min(pot), max(pot)
inter = range(mn, mx+1)
print([[a, b] for a, b in chain(*example.values()) if a in inter or b in inter])
[[5, 10], [13, 17]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.