Pythonの「RCut」関数

Source python intervals

後で説明する目的のためにすでに書かれたPythonの関数があるかどうか疑問に思います。そうでない場合、実装する最も簡単な方法は何でしょうか。私のコードが添付されています。

1から999999999の範囲があるとします。次のような番号のリストがあるとします。
[9, 44, 99]

それは戻るだろう
[(1,9), (10,44), (45,99), (100, 999999999)]

制限である数が入力数に含まれている場合は、それも処理する必要があります。
入力は
[1, 9, 44, 999999999]

リターンは次のようになります。
[(1,9), (10,44), (45, 999999999)]

いくつかの条件文と比較してforループを書くことはできますが、もっと「賢い方法」があるかどうか疑問に思います。

役立つかもしれないいくつかのデータマッサージ:
points = [1, 9, 44, 99]
points = sorted(list(set(points + [1, 999999999])))

更新情報:
alecxeに与えられた最終的なクレジット、あなたの刺激的なリスト内包ソリューション
に感謝します
l = sorted(list(set(points + [1, 999999999])))
[(l[i] + int(i != 0), l[i + 1]) for i in xrange(len(l) - 1)]

それらすべてを一行にまとめることはできますが、それは不必要だと思います。
推奨答え
pandas.cut()


[1,2,3,4,5,6,7,8,9,10] ---> [A,A,B,B,C,C,D,D,E,E]

R:
x  <- seq(1,10,1)
cut(x, breaks = seq(0,10,2), labels = c('A','B','C','D','E'))

Python:
import pandas
x = range(1, 11, 1)
pandas.cut(x, bins=range(0, 12, 2), labels=['A','B','C','D','E'])
その他答え 1
このアプローチが最適かどうかはわかりません。
>>> l = [1, 9, 44, 999999999]
>>> [(l[i] + int(i != 0), l[i + 1]) for i in xrange(len(l) - 1)]
[(1, 9), (10, 44), (45, 999999999)]

Python 3を使用している場合は、xrangerangeに置き換えます。

最初の例を機能させるには、境界を追加して追加する必要があることに注意してください。
>>> l = [9, 44, 109]
>>> low, high = 1, 999999999
>>> l = [low] + l + [high]
>>> [(l[i] + int(i != 0), l[i + 1]) for i in xrange(len(l) - 1)]
[(1, 9), (10, 44), (45, 109), (110, 999999999)]
その他答え 2
def myCut(low, high, points):
    answer = []
    curr = low
    for point in points:
        answer.append((curr, point))
        curr = point + 1
    answer.append((curr, high))
    return answer

>>> low = 1
>>> high = 999999999
>>> points = [9, 44, 109]
>>> myCut(low, high, points)
[(1, 9), (10, 44), (45, 109), (110, 999999999)]

this answerとその後の議論に触発されて、itertoolsを使用したより少ない行での解決策を次に示します。これは、itertools.chainitertools.izip(python2.7では; python3.xではzip)を使用して、リストの追加、並べ替え、および設定から生じる時間とスペースの複雑さを軽減します。このソリューションは、入力リストがすでにソートされていることを前提としていることに注意してください。失敗すると、誤った結果が生成されます。
cuts = [(i+1, j) for i,j in itertools.izip(itertools.chain([0], myList), itertools.chain(myList, [999999999]))]

>>> import itertools
>>> myList = [9, 44, 99]
>>> [(i+1, j) for i,j in itertools.izip(itertools.chain([0], myList), itertools.
chain(myList, [999999999]))]
[(1, 9), (10, 44), (45, 99), (100, 999999999)]
その他答え 3
回答のコードをtimeitと比較すると、リスト内包表記ソリューションに低値と高値を追加しなかったにもかかわらず、inspectorG4dgetのソリューションのパフォーマンスが大幅に向上しているようです(特にPython 3の場合)。
ls = [9, 44, 109, 200, 567, 894, 6879, 29823]

def f1(low, high, points):
    answer = []
    curr = low
    for point in points:
        answer.append((curr, point))
        curr = point + 1
    answer.append((curr, high))
    return answer

def f2(low, high, l):
    a = [(l[i] + int(i != 0), l[i + 1]) for i in range(len(l) - 1)]
    return a

if __name__ == '__main__':
    import timeit

    print(timeit.timeit("f1(1, 99999999, ls)", setup="from __main__ import f1, ls"))
    print(timeit.timeit("f2(1, 99999999, ls)", setup="from __main__ import f2, ls"))

結果(私のネットブックのpy3):
3.2064807919996383
8.850830605999363

関連記事

Ember 1.0.0:Ember.Stateはプラグインに移動されました:https://github.com/emberjs/ember-states
HTMLの要素を再利用する
Matplotlibでテキストをアニメーション化する方法は?
VimはPythonで視覚的な選択範囲の間の文字列を取得します
ジェネレータのthrowメソッドを使用している場合ではなく、例外TypeError警告が表示される場合があります