![](/img/trans.png)
[英]Generate all possible tuples combinations of given size for given range of values
[英]Generate list of range tuples with given boundaries in python
[編輯]我不確定這是否更好的代碼審查,如果是這樣,請遷移:)謝謝!
所以我們坐在這里,研究半學術問題。
給定一個start
, stop
和step
,生成一個范圍元組列表,這樣
gen_range(100, 140, 10)
會產生
[(100, 110), (110, 120), (120, 130), (130, 140)]
同時,如果事實它應該工作,比如說,迭代500M整數,步長為100而不是永遠。
我提出的實現如下:
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()
內部原因,上邊界應該是143,而不是150,因為這里的一些答案會產生。
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))
我不確定我是否正確理解了這個問題,但這可以通過列表理解來完成:
start = 100
stop = 140
step = 10
[ range(s,s+step+1,step) for s in range(start,stop,step)]
如果你只需要迭代你的列表元素,我強烈建議你使用生成器理解:
res = ( range(s,s+step+1,step) for s in range(start,stop,step))
您可以在一個循環中迭代它:
for range_piece in res:
do_something with it
這樣的事情:
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)]
如果(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:])
如果(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:])
我會把它變成一台發電機,因此可以處理大范圍。
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))
我會選擇生成器方法,但是如果你打算將這個東西解壓縮到一個明確的列表中,另一種看待它的方法就是你的元組元素和所有元素之間的關系非常簡單你需要做的是適當地調整長度。
def gen_range(start, stop, step):
items = ((stop-start) // step)
return [(start+(n*step), start+(n+1)*step) for n in range(items)]
我認為值得發布這個的唯一原因是我的第一個想法(以及評論查詢)是否可以逃避只需要在列表中詢問第n個元組而不必生成批次。 如果你不能,那么我就不會走這個角度了。
我認為發電機是一個很好的嘗試:
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)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.