Python 包含多值项的对分列表?关于完成这项任务的建议

Python 包含多值项的对分列表?关于完成这项任务的建议,python,list,bisect,Python,List,Bisect,我真的需要一些关于使用什么数据结构和函数来解决我试图执行的任务的建议。我只是不确定这里最好的方法 问题/任务:我有一个染色体起始和终止位置的列表。我试图找出最好的方法,将这些数据放入元组列表(?)或类似的列表中,然后在给定起始范围值的情况下将这些坐标平分。。我以前使用过二分法,但仅适用于包含单值项的列表,因此不确定进行多值比较的最佳方法是什么 例如,如果我有下面的基因 gene_name start_pos end_pos gene_A 100 200 gene_B 300 400 gene_C

我真的需要一些关于使用什么数据结构和函数来解决我试图执行的任务的建议。我只是不确定这里最好的方法

问题/任务:我有一个染色体起始和终止位置的列表。我试图找出最好的方法,将这些数据放入元组列表(?)或类似的列表中,然后在给定起始范围值的情况下将这些坐标平分。。我以前使用过二分法,但仅适用于包含单值项的列表,因此不确定进行多值比较的最佳方法是什么

例如,如果我有下面的基因

gene_name start_pos end_pos
gene_A 100 200
gene_B 300 400
gene_C 500 600
gene_D 700 800
gene_E 900 1000
我想用一个与正常起始和结束位置不匹配的起始和结束位置来查询这个列表,以返回匹配的基因

query_start = 550 query_end = 580 > should return gene_C 
query_start = 110 query end = 180 > should return gene_A
我已经尝试了我的方式通过,并作出了一些可笑的丑陋复杂的代码,但我知道必须有一个简单的/逻辑的方法来做到这一点,我正在努力提出正确的问题,文档/论坛搜索明智

如有任何有用的建议,将不胜感激


谢谢

将这些值放入字典是很自然的事情。在这里,我使用了基因名称作为字典键,并将它们对应的范围作为值

genes={'gene_A': [100,200],
    'gene_B': [300, 400],
    'gene_C': [500, 600],
    'gene_D': [700, 800],
    'gene_E': [900, 1000]}

#Takes as argument a dictionary of genes to check and a range in the form of a tuple
def gene_query(gene_data,gene_range):
    for gene in gene_data:
        if gene_range[0]>=gene_data[gene][0]:
            if gene_range[1]<=gene_data[gene][1]:
                return gene
    else:
        return "No genes match your query range"


print gene_query(genes, (550, 580))
print gene_query(genes, (110, 180))
genes={'gene_A':[100200],
“基因B”:[300400],
“基因C”:[500600],
"gene_D":[700800],,
“基因:[9001000]}
#将要检查的基因字典和元组形式的范围作为参数
def gene_查询(gene_数据、gene_范围):
对于gene_数据中的基因:
如果基因范围[0]>=基因数据[gene][0]:

如果首先是gene_range[1],以下是元组列表中的所有数据:

>>> txt='''\
... gene_name start_pos end_pos
... gene_A 100 200
... gene_B 300 400
... gene_C 500 600
... gene_D 700 800
... gene_E 900 1000'''
>>> 
>>> genes=[(name, int(d1), int(d2)) for name, d1, d2 in [line.split() for line in txt.splitlines()[1:]]]
>>> genes
[('gene_A', 100, 200), ('gene_B', 300, 400), ('gene_C', 500, 600), ('gene_D', 700, 800), ('gene_E', 900, 1000)]
一旦您有了这些,对于您的简单示例,您可以使用过滤器:

def query(genes, start, finish):
    return list(filter(lambda t: t[1]<start<t[2] and t[1]<finish<t[2], genes))

>>> query(genes, 550, 580)
[('gene_C', 500, 600)]
>>> query(genes, 110, 180)
[('gene_A', 100, 200)]
生成可以用作索引的关键元组列表:

>>> keys=[(t[1], t[2]) for t in genes]
>>> keys
[(100, 200), (300, 400), (500, 600), (700, 800), (900, 1000)]
现在,您可以使用键索引和对分查询基因:

>>> import bisect
>>> genes[bisect.bisect_left(keys, (550, 580))-1]
('gene_C', 500, 600)
>>> genes[bisect.bisect_left(keys, (110, 180))-1]
('gene_A', 100, 200)
对于更复杂的例子,你可以考虑配方。
>>> keys=[(t[1], t[2]) for t in genes]
>>> keys
[(100, 200), (300, 400), (500, 600), (700, 800), (900, 1000)]
>>> import bisect
>>> genes[bisect.bisect_left(keys, (550, 580))-1]
('gene_C', 500, 600)
>>> genes[bisect.bisect_left(keys, (110, 180))-1]
('gene_A', 100, 200)