Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在范围字典中查找值-python_Python_Dictionary_Range - Fatal编程技术网

在范围字典中查找值-python

在范围字典中查找值-python,python,dictionary,range,Python,Dictionary,Range,我正在比较两个文件的初始标识符列、起始值和结束值。第二个文件包含相应的标识符和另一个值列 前 文件1: A 200 900 A 1000 1200 B 100 700 B 900 1000 文件2: A 103 A 200 A 250 B 50 B 100 B 150 我想从第二个文件中查找包含在第一个文件中的范围内的所有值,以便我的输出如下所示: A 200 A 2

我正在比较两个文件的初始标识符列、起始值和结束值。第二个文件包含相应的标识符和另一个值列

文件1:

A     200     900
A     1000    1200
B     100     700
B     900     1000
文件2:

A     103
A     200
A     250
B     50
B     100
B     150
我想从第二个文件中查找包含在第一个文件中的范围内的所有值,以便我的输出如下所示:

A     200
A     250
B     100
B     150
# comparing...
if ident in d:
    if d[ident][0] <= val <= d[ident][1]:
        outfile.write(line+'\n')
现在,我已经从第一个文件创建了一个字典,其中包含一个范围列表: 前

然后,我遍历第二个文件并在范围字典中搜索值: 前


虽然这对相对较小的文件来说不是最优的,但是我有几个大文件,这个程序被证明效率非常低。我需要优化我的程序,使它运行得更快。

因为你有很大的范围,而你的问题本质上只是一堆比较,所以存储一个开始/结束元组几乎肯定比存储整个范围更快(特别是因为如果两个数字恰好重叠,那么您现在拥有的将复制范围中的大多数数字)

那么,您的比较结果如下所示:

A     200
A     250
B     100
B     150
# comparing...
if ident in d:
    if d[ident][0] <= val <= d[ident][1]:
        outfile.write(line+'\n')

上面的代码是我用来测试的;它在几秒钟内运行在一个
文件2
上,有一百万行。

您需要构建
范围(开始,结束)
?当您可以这样做时,这似乎是非常浪费的:

if START <= x <= END:
    # process

如果开始您可以尝试以下方法:

In [27]: ranges=defaultdict(list)

In [28]: with open("file1") as f:
    for line in f:
        name,st,end=line.split()
        st,end=int(st),int(end)
        ranges[name].append([st,end])
   ....:         

In [30]: ranges
Out[30]: defaultdict(<type 'list'>, {'A': [[200, 900], [1000, 1200]], 'B': [[100, 700], [900, 1000]]})

In [29]: with open("file2") as f:
    for line in f:
        name,val=line.split()
        val=int(val)
        if any(y[0]<=val<=y[1] for y in ranges[name]):
            print name,val
   ....:             
A 200
A 250
B 100
B 150
[27]中的
:范围=defaultdict(列表)
在[28]中:打开(“文件1”)作为f:
对于f中的行:
name,st,end=line.split()
st,end=int(st),int(end)
范围[name]。追加([st,end])
....:         
在[30]:范围内
Out[30]:defaultdict(,{'A':[200900],[10001200],'B':[100700],[9001000]})
在[29]中:以“打开”(“文件2”)作为f:
对于f中的行:
名称,val=line.split()
val=int(val)
如果有(y[0]
,则从集合导入defaultdict
ident_ranges=defaultdict(列表)
以open('file1.txt','r')作为f1
对于f1中的行:
ident,start,end=row.split()
开始,结束=int(开始),int(结束)
标识范围[ident]。追加((开始,结束))
将open('file2.txt','r')作为f2,将open('out.txt','w')作为输出:
对于f2中的行:
ident,value=line.split()
value=int(值)

如果有(开始巧妙的技巧:Python允许您在
中与
xrange
对象进行
比较,这比在
中使用
范围进行
要快得多,而且内存效率也要高得多

那么,你能做什么

from collections import defaultdict

rangedict = defaultdict(list)
...
rangedict[ident].append(xrange(start, end+1))
...

for i in rangedict:
    for r in rangedict[i]:
        if v in r:
            print >>outfile, line

标识符在两个文件中的显示顺序是否相同?值和范围是否总是按顺序排列?
In [27]: ranges=defaultdict(list)

In [28]: with open("file1") as f:
    for line in f:
        name,st,end=line.split()
        st,end=int(st),int(end)
        ranges[name].append([st,end])
   ....:         

In [30]: ranges
Out[30]: defaultdict(<type 'list'>, {'A': [[200, 900], [1000, 1200]], 'B': [[100, 700], [900, 1000]]})

In [29]: with open("file2") as f:
    for line in f:
        name,val=line.split()
        val=int(val)
        if any(y[0]<=val<=y[1] for y in ranges[name]):
            print name,val
   ....:             
A 200
A 250
B 100
B 150
from collections import defaultdict
ident_ranges = defaultdict(list)
with open('file1.txt', 'r') as f1
    for row in f1:
        ident, start, end = row.split()
        start, end = int(start), int(end)
        ident_ranges[ident].append((start, end))
with open('file2.txt', 'r') as f2, open('out.txt', 'w') as output:  
    for line in f2:
        ident, value = line.split()
        value = int(value)
        if any(start <= value <= end for start, end in ident_ranges[ident]):
            output.write(line)
from collections import defaultdict

rangedict = defaultdict(list)
...
rangedict[ident].append(xrange(start, end+1))
...

for i in rangedict:
    for r in rangedict[i]:
        if v in r:
            print >>outfile, line