2

我厌倦了多种方法,但未能完成这项工作。他们都只使用 2 个列表或列表范围。最有希望的是:

infile = open('file','r')

for line in infile:
    line = line.split()
    f = range(int(line[0]),int(line[1]))

results_union = set().union(*f)
print results_union

我有一个文件的开始,结束位置是这样的:(排序)

1 5
1 3
1 2
2 4
3 6
9 11
9 16
12 17

我希望输出为:

1 6
9 17
4

3 回答 3

4

尝试以下操作:

def group(data):
    data = sorted(data)
    it = iter(data)
    a, b = next(it)
    for c, d in it:
        if b >= c:  # Use `if b > c` if you want (1,2), (2,3) not to be
                    # treated as intersection.
            b = max(b, d)
        else:
            yield a, b
            a, b = c, d
    yield a, b


with open('file') as f:
    data = [map(int, line.split()) for line in f]

for a, b in group(data):
    print a, b

例子:

>>> data = (9,16), (1,5), (1,3), (1,2), (3,6), (9,11), (12,17), (2,4),
>>> list(group(data))
[(1, 6), (9, 17)]
于 2013-09-11T16:27:07.907 回答
1

以下看起来很有希望。第一部分基于您的方法。第二部分只是在范围的联合中寻找连续的区间。

intervals = []
with open('contigous_input.txt', 'r') as infile:
    for line in infile:
        start, stop = sorted(map(int, line.split()))
        intervals.append(range(start, stop+1))

union = list(set().union(*intervals))
print union

results = []
i = start = 0
j = i + 1
while j < len(union):
    if union[j] != union[i]+1:
        results.append( (union[start], union[j-1]) )
        if j == len(union):
            break
        i = start = j
        j = i + 1
    else:
        i, j = j, j + 1

if start != j-1:
    results.append( (union[start], union[j-1]) )

print results

输出:

[1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17]
[(1, 6), (9, 17)]
于 2013-09-11T16:48:58.317 回答
0

您应该使用 2 元组而不是range函数,因为range返回一个list. 这是一个简单的函数,如果可能的话,它将结合你的两个 2 元组:

def combine_bounds(x, y):
  a, b = sorted([x, y])
  if a[1]+1 >= b[0]:
    return (a[0], max(a[1],b[1]))

样本输出:

>>> combine_bounds((1,2), (3,4))
(1, 4)
>>> combine_bounds((1,100), (3,4))
(1, 100)
>>> combine_bounds((1,2), (4,10))
>>> combine_bounds((1,3), (4,10))
(1, 10)
>>> combine_bounds((1,6), (4,10))
(1, 10)
>>> combine_bounds((10,600), (4,10))
(4, 600)
>>> combine_bounds((11,600), (4,10))
(4, 600)
>>> combine_bounds((9,600), (4,10))
(4, 600)
>>> combine_bounds((1,600), (4,10))
(1, 600)
>>> combine_bounds((12,600), (4,10))
>>> combine_bounds((12,600), (4,10)) is None
True

None在 Python 中是一个错误值,因此您可以使用combine_bounds条件中的结果。如果它返回None(类似于False),则没有交集。如果它返回一个 2 元组,那么就有一个交集,返回值就是结果。

我没有为你做所有的工作(你仍然需要弄清楚如何在输入上使用它来获得你想要的输出),但这应该会让你朝着正确的方向前进!

于 2013-09-11T16:06:16.247 回答