【问题标题】:Removing overlapping tuple values using Python使用 Python 删除重叠的元组值
【发布时间】:2017-11-22 10:38:30
【问题描述】:

我有一个包含 N 个元组的元组列表(我们将其命名为 yz_list),这些元组的开始和结束值如下:(start, end),由以下示例表示:

yz_list = [(0, 6), (1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12), (18, 24)]

并且我想删除与先前保存的元组的间隔重叠的所有值。在上面显示的序列上代表这种情况的输出是:

 result = [(0,6), (6,12), (18,24)]

我怎样才能使用 Python 实现这个结果?

编辑#1

下面的代码是我生成这个元组的代码:

for i, a in enumerate(seq):
    if seq[i:i+multiplier] == "x"*multiplier:
        to_replace.append((i, i+multiplier))

for i, j in enumerate(to_replace):
    print(i,j)
    if i == 0:
        def_to_replace.append(j)
    else:
        ind = def_to_replace[i-1]
        print(j[0]+1, "\n", ind)
        if j[0]+1 not in range(ind[0], ind[1]):
            def_to_replace.append(j)
    # print(i, j)
print(def_to_replace)
for item in def_to_replace:
    frag = replacer(frame_calc(seq[:item[0]]), rep0, rep1, rep2)
    for k, v in enumerate(seq_dup[item[0]:item[1]]):
        seq_dup[int(item[0]) + int(k)] = list(frag)[k]

return "".join(seq_dup)

在使用 TDD 进行开发时,我正在逐步进行开发,现在我正在考虑如何实现重叠元组的删除。我真的不知道将它们用作集合是否是个好主意,并查看重叠的项目。

生成结果列表的伪代码为:

for item in yz_list:
    if is not yz_list first item:
        gets item first value
        see if the value is betwen any of the values from tuples added on the result list

【问题讨论】:

  • 你是如何手工完成的?你需要什么代码来执行这个过程?那个代码有什么问题?请阅读并遵循帮助文档中的发布指南。 on topichow to ask 在这里申请。 StackOverflow 不是设计、编码、研究或教程服务。
  • 嘿 Prune,我是手工完成的。我正在尝试执行帖子上现在可用的代码(对不起,混乱)。
  • 您之前保存的用于从输入生成输出的元组是什么?例如,为什么前两个元组在值 6 上分裂?
  • @ViniciusMesel 感谢您的更新。否决票和关闭投票已撤回。
  • 当你得到解决方案时,请记得给有用的东西投票并接受你最喜欢的答案(即使你必须自己写),这样 Stack Overflow 才能正确存档问题。跨度>

标签: python algorithm


【解决方案1】:

这可能有效。没有花哨的东西,只需手动处理每个元组以查看其中一个值是否在已保存元组的设置范围内:

yz_list = [(0, 6), (1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12), (18, 24)]

result = [yz_list[0]]

bounds = yz_list[0][0], yz_list[0][1]

for tup in yz_list[1:]:
    if tup[0] in range(bounds[0], bounds[1]) or tup[1] in range(bounds[0], bounds[1]):
        pass
    else:
        result.append(tup)

print result # [(0, 6), (6, 12), (18, 24)]

【讨论】:

  • 如果将元组(19, 23)附加到yz_list,则结果为[(0, 6), (6, 12), (18, 24), (19, 23)]。这是不正确的,因为(19, 23)(18, 24) 重叠。
【解决方案2】:

这是一个使用高效二进制搜索计算重叠的类,以及显示其用于解决您的问题的代码。使用 python3 运行。

import bisect
import sys

class Overlap():

    def __init__(self):
        self._intervals = []

    def intervals(self):
        return self._intervals

    def put(self, interval):
        istart, iend = interval
        # Ignoring intervals that start after the window.                                       
        i = bisect.bisect_right(self._intervals, (iend, sys.maxsize))

        # Look at remaining intervals to find overlap.                                          
        for start, end in self._intervals[:i]:
            if end > istart:
                return False
        bisect.insort(self._intervals, interval)
        return True


yz_list = [(0, 6), (1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12), (18, 24)]

ov = Overlap()
for i in yz_list:
    ov.put(i)

print('Original:', yz_list)
print('Result:', ov.intervals())

输出:

Original: [(0, 6), (1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12), (18, 24)]                 
Result: [(0, 6), (6, 12), (18, 24)] 

【讨论】:

    【解决方案3】:
    yz_list = [(0, 6), (1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12), (18, 24)]
    
    result = []
    for start, stop in yz_list:
        for low, high in result:
            if (low < start < high) or (low < stop < high):
                break
        else:
            result.append((start, stop))
    

    这提供了所需的输出,并且很容易看出它是如何工作的。 else 子句基本上只是意味着“如果我们没有 break 退出循环就运行它”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 2018-11-27
      • 2019-03-07
      • 2017-06-17
      • 2019-03-21
      相关资源
      最近更新 更多