2

リスト内の数字が連続しているかどうかを調べるための最もpythonicな方法を見つけようとしています。背景を説明するために、フォルダーに存在する収集された番号のリストがあり、欠落している番号を見つける必要があります。

すべての数字を集めて、そこにあるべき数字の範囲 (先頭、末尾 + 1) から別のリストを作成します。不足しているすべての数字を表示するものを非常に簡単に作成しました。

missing = [x for x in existingNumbers if x not in shouldBeNumbers]

問題は、それらすべてを印刷すると、凝縮される可能性のある数字がたくさんあることです (つまり、1、2、3、4、7、10 は 1-4、7、10 として印刷される可能性があります)。欠落している膨大な量の数字です。

私は2つのアプローチを試しました:

どちらの方法でも、frameRange は range(startFrame, endFrame+1) であり、frameList は現在存在するものから生成されたリストです。

1)

    for x in frameRange:
        if x not in frameList:
            if originalFrame == None:
                originalFrame = x
            elif originalFrame:
                if lastFrame == None:
                    lastFrame = x
                elif lastFrame:
                    if lastFrame == x-1:
                        lastFrame = x
                    else:
                        if originalFrame != lastFrame:
                            missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
                            originalFrame = x
                            lastFrame = x
                        else:
                            missingFrames.append(str(originalFrame))
                            originalFrame = x
                            lastFrame = x
        if x == endFrame:
            if originalFrame != lastFrame:
                missingFrames.append(str(originalFrame)+"-"+str(lastFrame))
                originalFrame = x
                lastFrame = x
            else:
                missingFrames.append(str(originalFrame))
                originalFrame = x
                lastFrame = x

2)

    i = 0
    while i < len(frameRange):
        if frameRange[i] in frameList:
            i += 1
        else:
            if i + 1 < len(frameRange):
                if frameRange[i + 1] in frameList:
                    missingFrames.append(str(frameRange[i]))
                    i += 1
                else:
                    j = 1
                    while frameRange[i+j] not in frameList:
                        aheadFrameNumber = int(str(j))
                        if i + j + 1 < len(frameRange):
                            j += 1
                        else:
                            break
                    missingFrames.append(str(frameRange[i])+"-"+str(frameRange[aheadFrameNumber]))
                    if i + aheadFrameNumber + 1 < len(frameRange):
                        i += aheadFrameNumber + 1
            else:
                missingFrames.append(str(frameRange[i]))

最初の方法は機能していましたが、最後のフレームをチェックする現在のフレームで発生するため、最後のフレームがなくなると、最後に欠落しているセクションがリストに追加されません。2 番目の方法では、先に進むときにインデックスの例外が発生し続けたため、if ステートメントですべてをラップし続ける必要がありました。

一歩下がって、再考し、別の方法でアプローチする必要があると思います。関数がわからないため、まだ考えていないPythonでこれを行うためのはるかに良い方法があるかどうか疑問に思っています。どちらの方法も少し手に負えなくなり始めました。

4

2 に答える 2

1
def find_missing_range(my_numbers, range_min, range_max):
    expected_range = set(range(range_min, range_max + 1))
    return expected_range - set(my_numbers)

def numbers_as_ranges(numbers):
    ranges = []
    for number in numbers:
        if ranges and number == (ranges[-1][-1] + 1):
            ranges[-1] = (ranges[-1][0], number)
        else:
            ranges.append((number, number))
    return ranges

def format_ranges(ranges):
    range_iter = (("%d" % r[0] if r[0] == r[1] else "%d-%d" % r) for r in ranges)
    return "(" + ", ".join(range_iter) + ")"

def main(my_numbers, range_min, range_max):
    numbers_missing = find_missing_range(my_numbers, range_min, range_max)
    ranges = numbers_as_ranges(numbers_missing)
    return format_ranges(ranges)

if __name__ == '__main__':
    range_min, range_max = 1, 40
    print main([1, 4, 6, 10, 12], range_min, range_max)
    print main([1, 2, 3, 4, 10, 20], range_min, range_max)

(2-3, 5, 7-9, 11, 13-40)
(5-9, 11-19, 21-40)
于 2011-08-16T15:31:15.123 に答える