如何合并/扩展一个列表以包含另一个包含更多信息的列表中的元素?问题是发生移位的索引不是恒定的。
[1,2,3,4], [2,3,4,5], [5,6,7,8], [7,8,9,10]
进入[1,2,3,4,5,6,7,8,9,10]
列表是时间序列的定时快照,因此元素的顺序和顺序应保持不变,并且允许重复元素,即
[1,2,3,4,5,5,6,7,8]
和 [4,5,5,6,7,8,9,10,11]
第二个列表包含第一个列表中的元素以及更多元素,您可以说第二个列表与第一个列表相同,但它已移至左侧并添加了更多元素。
例如
l1 = [1,2,3,4,5,5,6,7,8]
l2 = [4,5,5,6,7,8,9,10,11]
结果
l3 = [1,2,3,4,5,5,6,7,8,9,10,11]
您可以检查 l1 的结尾子列表并将它们与 l2 的开头进行比较。如果它们匹配,则将它们合并。
def merge_series(l1,l2):
for i in range(len(l1)):
#check if the end sub-list of l1 matches the beginning sublist of l2 for this index
if l1[i:] == l2[:(len(l1)-i)]:
#marge them if they do
l1.extend(l2[(len(l1)-i):])
return l1
# there is no match, just merge lists
l1.extend(l2)
return l1
您可以使用 next 函数来识别第一个列表中不再位于第二个列表开头的部分,并添加相应的下标以形成第三个列表:
l1 = [1,2,3,4,5,5,6,7,8]
l2 = [4,5,5,6,7,8,9,10,11]
start = l1.index(l2[0]) if l2[0] in l1 else len(l1)
keep = next(i for i in range(start,len(l1)+1) if l1[i:] == l2[:len(l1)-i])
l3 = l1[:keep] + l2
print(l3)
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11]
为了加快速度,可以使用二分搜索来识别起点。由于重复,它无法提供精确的范围,但如果列表非常大,它可能会减少获取起始位置所需的时间:
from bisect import bisect_left
l1 = [1,2,3,4,4,5,5,6,7,8]
l2 = [4,5,5,6,7,8,9,10,11]
start = bisect_left(l1,l2[0])
keep = next(i for i in range(start,len(l1)+1) if l1[i:] == l2[:len(l1)-i])
l3 = l1[:keep]+l2
print(l3)
[1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11]
根据您的第二个示例,甚至允许重复。因此,您可以使用字典来跟踪第一个列表中的元素及其计数,并将其与第二个列表进行比较并相应地追加/更新。
l1 = [1,2,3,4,5,5,6,7,8]
l2 = [4,5,5,6,7,8,9,10,11]
lookup = {}
for elem in l1:
if elem in lookup:
lookup[elem] += 1
else:
lookup[elem] = 1
for elem in l2:
if elem in lookup and lookup[elem] > 0:
lookup[elem] -= 1
else:
l1.append(elem)
print(l1)
输出:
[1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11]
IIUC,你可以尝试(基于假设“第二个列表与第一个列表相同,但它已向左移动并添加了更多元素”):
l1 = np.array([1,2,3,4,5,5,6,7,8])
l2 = np.array([4,5,5,6,7,8,9,10,11])
idx = np.searchsorted(l1, l2[0])
out = np.hstack([l1[:idx], l2])
print(out)
打印:
[ 1 2 3 4 5 5 6 7 8 9 10 11]