将一个列表中的两个子列表合并为一个子列表python

时间:2018-11-01 17:05:50

标签: python list dictionary key

我有一本字典,其中有一个列表,该列表具有成对的数字作为子列表, 我正在尝试检查子列表之间是否有重叠。

{'5ykw.pdb': [[10, 22], [33, 40], [39, 51], [63, 71], [94, 105]]}

[33,40]和[39,51]之间有重叠,因此我想将它们合并为:

{'5ykw.pdb': [[10, 22], [33, 51], [63, 71], [94, 105]]}

3 个答案:

答案 0 :(得分:0)

您可以将reduce与自定义merge函数一起使用来创建新列表:

from functools import reduce

def merge(acc, curr):
    if not len(acc) or acc[-1][1] < curr[0]:
        acc.append(curr)
        return acc
    acc[-1][1] = curr[1] # update last element in accumulator
    return acc

data = {'5ykw.pdb': [[10, 22], [33, 40], [39, 51], [63, 71], [94, 105]]}
data['5ykw.pdb'] = reduce(merge, data['5ykw.pdb'], [])
print(data)
# {'5ykw.pdb': [[10, 22], [33, 51], [63, 71], [94, 105]]}

答案 1 :(得分:0)

您可以使用此功能简单地“消除重叠”列表:

def deoverlap(lst):
    if not lst:
        return []
    lst = [sorted(pair) for pair in lst]  # sort pairs (leave out if not needed)
    lst = sorted(lst)  # sort by first item (breaking ties by second item)
    out = []
    prev = lst[0]
    for pair in lst[1:]:
        if prev[1] >= pair[0]:
            if prev[1] < pair[1]:
                prev[1] = pair[1]
        else:
            out.append(prev)
            prev = pair
    out.append(prev)
    return out

dct = {'5ykw.pdb': [[10, 22], [33, 40], [39, 51], [63, 71], [94, 105]]}

dct['5ykw.pdb'] = deoverlap(dct['5ykw.pdb'])

print(dct)  # prints {'5ykw.pdb': [[10, 22], [33, 51], [63, 71], [94, 105]]}

这里唯一的假设是deoverlap()的输入是可比较类型(通常是数字)的成对列表,其中每对都是长度为2的列表。

对在内部进行排序,然后按第一项进行排序,如果前一对的最大值≥当前对的最小值,则将其合并。如果在相等时不应该合并,则deoverlap()的第9 行应变为

        if prev[1] > pair[0]:

答案 2 :(得分:0)

您可以使用广度优先搜索的递归形式:

def overlap(a, b) -> bool:
  return a[-1] >= b[0] and a[-1] < b[-1]

def group(d, _c, seen):
   return [_c, 
     [i if i not in seen else group(d, i, seen+[i]) for i in d if overlap(_c, i)]]

r = {'5ykw.pdb': [[10, 22], [33, 40], [39, 51], [63, 71], [94, 105]]}
new_data = [group(r['5ykw.pdb'], i, []) for i in r['5ykw.pdb'] if not any(overlap(c, i) for c in r['5ykw.pdb'])]
final_data = [a if not b else [a[0], max(h for _, h in b)] for a, b in new_data]

输出:

[[10, 22], [33, 51], [63, 71], [94, 105]]

这也适用于具有大量重叠的输入:

r = {'5ykw.pdb':[[15, 20], [18, 21], [19, 30]]}
new_data = [group(r['5ykw.pdb'], i, []) for i in r['5ykw.pdb'] if not any(overlap(c, i) for c in r['5ykw.pdb'])]
final_data = [a if not b else [a[0], max(h for _, h in b)] for a, b in new_data]

输出:

[[15, 30]]