14

インデックスを持つリストのリストがあるとします[[start, end], [start1, end1], [start2, end2]]

例のように:

[[0, 133], [78, 100], [25, 30]].

リスト間の重複をチェックし、長さが長いリストを毎回削除するにはどうすればよいですか? そう:

>>> list = [[0, 133], [78, 100], [25, 30]]
>>> foo(list)
[[78, 100], [25, 30]]

これは私がこれまでにやろうとしたことです:

def cleanup_list(list):
    i = 0
    c = 0
    x = list[:]
    end = len(x)
    while i < end-1:
        for n in range(x[i][0], x[i][1]):
            if n in range(x[i+1][0], x[i+1][1]):
                list.remove(max(x[i], x[i+1]))
        i +=1
    return list

しかし、複雑であることに加えて、適切に機能していません。

 >>>cleanup_list([[0,100],[9,10],[12,90]])
 [[0, 100], [12, 90]]

どんな助けでも大歓迎です!

編集:

他の例は次のとおりです。

>>>a = [[0, 100], [4, 20], [30, 35], [30, 78]]
>>>foo(a)
[[4, 20], [30, 35]]

>>>b = [[30, 70], [25, 40]]
>>>foo(b)
[[25, 40]]

基本的に、別のリストと重複する最長のリストをすべて削除しようとしています。この場合、リストの長さが等しいことを心配する必要はありません。

ありがとう!!

4

5 に答える 5

3

これは最速の解決策ではないかもしれませんが、本当に冗長で明確だと思います。

a = [[2,100], [4,10], [77,99], [38,39], [44,80], [69,70], [88, 90]]

# build ranges first
def expand(list):
    newList = []
    for r in list:
        newList.append(range(r[0], r[1] + 1))
    return newList


def compare(list):
    toBeDeleted = []
    for index1 in range(len(list)):
        for index2 in range(len(list)):
            if index1 == index2:
                # we dont want to compare ourselfs
                continue
            matches = [x for x in list[index1] if x in list[index2]]
            if len(matches) != 0: # do we have overlap?
                ## compare lengths and get rid of the longer one
                if   len(list[index1]) > len(list[index2]):
                    toBeDeleted.append(index1)
                    break
                elif len(list[index1]) < len(list[index2]):
                    toBeDeleted.append(index2)
    # distinct
    toBeDeleted = [ toBeDeleted[i] for i,x in enumerate(toBeDeleted) if x not in toBeDeleted[i+1:]] 
    print len(list)
    # remove items
    for i in toBeDeleted[::-1]:
        del list[i] 
    return list


print(compare(expand(a)))
于 2013-05-01T08:42:54.107 に答える
2

あなたのコードの問題の1つは、あるリストに別のリストが含まれている状況を処理できないことだと思います。たとえば、 を[0,100]含みます[9,10]。[0,100] で n をループし、n が [9,10] に入ると、条件ステートメントif n in range(x[i+1][0], x[i+1][1])がトリガーされます。次に、組み込み関数maxは と を比較[0, 100]しますが、リストの最初の数値を比較するため[9, 10]、残念ながらmax戻ります。[9,10]したがって、間違った要素を削除します。

私はあなたが望む効果を達成するために別の方法を試みています. リスト自体を操作するのではなく、新しいリストを作成します。要件を満たしている場合は、新しい要素を条件付きで追加します。

def cleanup_list(lists):
    ranges = []
    for l in lists:
        to_insert = True
        for i in ranges:
            r = range(i[0],i[1])
            # if l overlaps with i, but l does not contain i
            if l[0] in r or l[1] in r:
                if (l[1]-l[0]) < len(r):
                    ranges.remove(i)
                else:
                    to_insert = False
            # l contains i
            if l[0]<i[0] and l[1]>i[1]:
                to_insert = False
        if to_insert:
            ranges.append(l)
    return ranges
于 2013-05-01T06:08:11.950 に答える
1
  1. すべてのアイテムを長さで昇順で並べ替えます。

  2. それらをセグメント ツリーに追加し、重複するアイテムを無視します。

于 2013-05-01T06:07:22.160 に答える