Python 如何有效地覆盖两个字符串,其中一个字符串优先于另一个?
我有两个字符串作为文件范围的缓冲区。我想从这个“文件”中读取字节,以便优先从第一个字符串中读取字节,而不是从第二个字符串中读取字节,其中存在重叠 在下面的示例中,r1和r2分别表示文件的范围,其中包括字符串以及开始和结束偏移量。我对示例进行了格式化,以便更清楚地显示字符串在文件中的位置Python 如何有效地覆盖两个字符串,其中一个字符串优先于另一个?,python,range,overlap,Python,Range,Overlap,我有两个字符串作为文件范围的缓冲区。我想从这个“文件”中读取字节,以便优先从第一个字符串中读取字节,而不是从第二个字符串中读取字节,其中存在重叠 在下面的示例中,r1和r2分别表示文件的范围,其中包括字符串以及开始和结束偏移量。我对示例进行了格式化,以便更清楚地显示字符串在文件中的位置 def prioritized_read(range1, range2, read_start, read_end): # This is the bit I don't know how to writ
def prioritized_read(range1, range2, read_start, read_end):
# This is the bit I don't know how to write
r1 = ("ABCDEF", (0,6))
r2 = ( "DEF", (1,4))
assert prioritized_read(r1, r2, 0, 6) == "ABCDEF"
r1 = ("ABC", (0,3))
r2 = ( "DEF", (1,4))
assert prioritized_read(r1, r2, 1, 4) == "BCF"
r1 = ( "ABC", (2,5))
r2 = ("DEF", (0,3))
assert prioritized_read(r1, r2, 0, 4) == "DEAB"
r1 = ( "A", (1,2))
r2 = ("DEF", (0,3))
assert prioritized_read(r1, r2, 0, 3) == "DAF"
r1 = ("ABC", (0,3))
r2 = ( "DEF", (3,6))
assert prioritized_read(r1, r2, 3, 6) == "DEF"
read\u start
和read\u end
始终由r1
和r2
的端点限定
这里的示例范围很小,但在我的应用程序中,它们可能会超过10亿,因此我正在寻找一种节省时间和内存的解决方案
我考虑过把这个发到你的邮箱。看起来这应该是一个简单而明显的过程。。。但它打败了我
注意,这里我不是真正从文件中读取,所以我不能使用涉及Python文件对象的解决方案。我只是使用文件作为一个方便的类比。类似这样的东西可以为您提供所需的输出:
def prioritized_read(r1, r2, start, end):
s = [''] * max(r1[1][1], r2[1][1])
s[r2[1][0]:r2[1][1]] = r2[0]
s[r1[1][0]:r1[1][1]] = r1[0]
return ''.join(s[start:end])
这假定其中一个范围始终以
0
开头,并且这些范围不是不相交的。如果范围较大,这可能不利于内存利用。间隔应划分为子间隔。让我在这个例子中解释一下:
r1 = ( "ABC", (2,5))
r2 = ("DEF", (0,3))
assert prioritized_read(r1, r2, 0, 4) == "DEAB"
子间隔的边界是所有开始编号和结束编号,即:0,2,3,4,5
。读取开始之前和读取结束之后的数字可以忽略,因此5为空。我们现在有了0,2,3,4
。不太明显的是,位于range1
范围内的range2
边界也可以忽略,因此3也被排除在外。边界是0,2,4
,这意味着子接口是0-2
和2-4
剩下的很简单。我们从具有所需范围的数据源读取数据-尊重优先级。范围不从零开始,因此必须考虑偏移
def prioritized_read(range1, range2, read_start, read_end):
d1, r1 = range1
d2, r2 = range2
bset = set((read_start, read_end))
for b in r1:
if read_start < b < read_end:
bset.add(b)
for b in r2:
if not r1[0] < b < r1[1] and read_start < b < read_end:
bset.add(b)
boundaries = sorted(bset)
output = []
for i in range(len(boundaries) - 1):
start, end = boundaries[i], boundaries[i+1]
if r1[0] <= start < r1[1]:
# read from #1
output.append(d1[start-r1[0]:end-r1[0]])
elif r2[0] <= start < r2[1]:
# read from #2
output.append(d2[start-r2[0]:end-r2[0]])
else:
raise ValueError("no data source for {}:{}".format(start, end))
return "".join(output)
def优先读取(范围1、范围2、读取开始、读取结束):
d1,r1=范围1
d2,r2=范围2
bset=设置((读取开始,读取结束))
对于r1中的b:
如果读取开始如果r1[0]是这样,您从中读到了什么?你的内存里有所有的数据吗?您正在阅读网络流吗?这可能会影响答案的性质。所有数据都将存储在内存中。