在范围字典中查找值-python
我正在比较两个文件的初始标识符列、起始值和结束值。第二个文件包含相应的标识符和另一个值列 前 文件1:在范围字典中查找值-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
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