11

[編集]これがコードレビューに適しているかどうかはわかりません。もしそうなら、移行してください:)ありがとう!

それで、私たちはここに座って、半学術的な問題に取り組んでいました。

、、を指定するとstart、範囲タプルのリストが生成され、次のようになります。stopstep

gen_range(100, 140, 10)

を生成します

[(100, 110), (110, 120), (120, 130), (130, 140)]

また、それが機能するはずであるという事実を考えると、たとえば、100のステップで500Mの整数を反復し、永遠にかかることはありません。

私が思いついた実装は次のとおりです。

def gen_range(start, stop, step):
    llist = range(start, stop+step, step)
    batch_list = []

    if llist[-1] > stop:
        llist[-1] = stop

    for a, b in enumerate(llist[:-1]):
        batch_list.append((llist[a], llist[a+1]))

    print batch_list

gen_range(100000000,600000000,100)

しかし、私はそれがより効率的な(コード長に関しても)方法で実行できると考えるのをやめることはできません。助言がありますか?

[編集]

私が指摘するのを忘れた一つのこと。範囲の境界がステップと等しくない場合、つまり次の場合があります。

gen_range(100, 143, 10)

range()内部のために、ここでいくつかの答えが生成されるように、上限は150ではなく143である必要があります。

4

7 に答える 7

9

本当に短い方法:

ranges = [(n, min(n+step, stop)) for n in xrange(start, stop, step)]

より冗長な方法:

おそらくジェネレーターを介して?

def gen_range(start, stop, step):
    current = start
    while current < stop:
        next_current = current + step
        if next_current < stop:
            yield (current, next_current)
        else:
            yield (current, stop)
        current = next_current

この関数を呼び出すと、各タプルを順番に生成するジェネレーターオブジェクトが得られます。次のように使用します。

for block in gen_range(100000000,600000000,100):
    print block

これは出力します...

(100000000,100000100)
(100000100,100000200)
(100000200,100000300)
...
(599999900,600000000)

stop-startの偶数倍であることが常に確実である場合は、ジェネレータ式を使用してこれをさらに簡単に行うことができます。step

ranges = ((n, n+step) for n in xrange(start, stop, step))

# Usage
for block in ranges:
    print block

また、ジェネレーターをリストに変換し、結果全体をメモリに保持する場合は、単純に次のアドレスに渡すことができますlist()

all_ranges = list(gen_range(100000000,600000000,100))
于 2012-12-27T02:43:15.553 に答える
2

たぶんコード長に関して(b - a) % c == 0

def gen_range(a, b, c):
    return [(i, i + c) for i in range(a, b, c)]

また

def gen_range_2(a, b, c):
    s = range(a, b + c, c)
    return zip(s, s[1:])

http://ideone.com/VhY215を参照してください

場合(b - a) % c != 0

def gen_range(a, b, c):
    return [(i, i + c) for i in range(a, b - ((b - a) % c), c)]

また

def gen_range_2(a, b, c):
    s = range(a, b - ((b - a) % c) + c, c)
    return zip(s, s[1:])

http://ideone.com/i3Pq69を参照してください

于 2012-12-27T02:44:54.667 に答える
1

このようなもの:

In [48]: it=iter(xrange(100,200,10))

In [49]: it1=iter(xrange(110,210,10))

In [50]: [(next(it),next(it1)) for _ in range(10)]
Out[50]: 
[(100, 110),
 (110, 120),
 (120, 130),
 (130, 140),
 (140, 150),
 (150, 160),
 (160, 170),
 (170, 180),
 (180, 190),
 (190, 200)]

または使用zip()

In [55]: it=iter(xrange(100,200,10))

In [56]: it1=iter(xrange(110,210,10))

In [57]: [(x,y) for x,y in zip(it,it1)]
Out[57]: 
[(100, 110),
 (110, 120),
 (120, 130),
 (130, 140),
 (140, 150),
 (150, 160),
 (160, 170),
 (170, 180),
 (180, 190),
 (190, 200)]
于 2012-12-27T02:44:12.063 に答える
1

問題を正しく理解したかどうかはわかりませんが、これはリスト内包表記で簡単に行うことができます。

start = 100
stop = 140
step = 10
[ range(s,s+step+1,step) for s in range(start,stop,step)]

リスト要素を一度に1つずつ繰り返す必要がある場合は、代わりにジェネレーター内包表記を使用することを強くお勧めします。

res = ( range(s,s+step+1,step) for s in range(start,stop,step))

サイクルでそれを繰り返すことができます:

for range_piece in res:
    do_something with it
于 2012-12-27T02:45:04.597 に答える
1

私はそれをジェネレーターにして、それが巨大な範囲を処理できるようにします。

def gen_range(start, stop, step):
    a, b = start, start+step
    while b <= stop:
        yield a, b
        a, b = b, b+step

print list(gen_range(100, 140, 10))
于 2012-12-27T02:49:09.383 に答える
1

ジェネレーターのアプローチを使用しますが、明示的なリストに展開する場合、別の見方をすれば、タプルの要素とすべての要素の間に非常に単純な関係があるということです。あなたがする必要があるのは、長さを適切に範囲指定することです。

def gen_range(start, stop, step):
   items = ((stop-start) // step)
   return [(start+(n*step), start+(n+1)*step) for n in range(items)]

これを投稿する価値があると私が考えた唯一の理由は、ロットを生成せずにリスト内のn番目のタプルを要求するだけで解決できるかどうかを最初に考えた(したがってコメントクエリ)ということです。あなたができないなら、私はこの角度を下がらないでしょう。

于 2012-12-27T03:24:26.613 に答える
1

ジェネレーターは良い試みだと思います:

def gen_range(start, stop, step):
    while start < stop:
        yield (start, min(start + step, stop))
        start = start + step

if __name__ == '__main__':
    print [x for x in gen_range(100, 143, 10)]
于 2012-12-27T04:34:53.153 に答える