对于我的生活,我看不出怎么做。我需要使用python在一系列数字中收集几个集合的非重叠端点。
例如,用户可以输入一系列10
和两套2
和3
。我需要在这个范围内得到这些集合的终点,以便:
set 2 groupings: 1-2,6-7
set 3 groupings: 3-5,8-10
任何单个组的范围,组数和大小都是任意的。我不能超出范围,所以没有半套。
我一直认为应该有一个简单的公式,但我无法想出来。
修改的
根据范围12的示例输入请求,以及设置1,2和3,输出应为:
set 1: 1,7
set 2: 2-3,8-9
set 3: 4-6,10-12
尽可能接近,我正在寻找某种累加器模式。像这样的伪代码:
for each miniRange in range:
for each set in sets:
listOfCurrSetEndpoints.append((start, end))
答案 0 :(得分:2)
我认为没有一个很好的内置解决方案。 (如果有一个内置的等效于Haskell的scan
函数会更容易。)但这很简洁:
>>> import itertools
>>> from collections import defaultdict
>>> partition_lengths = [1, 2, 3]
>>> range_start = 1
>>> range_end = 12
>>> endpoints = defaultdict(list)
>>> for p_len in itertools.cycle(partition_lengths):
... end = range_start + p_len - 1
... if end > range_end: break
... endpoints[p_len].append((range_start, end))
... range_start += p_len
...
>>> endpoints
defaultdict(<type 'list'>, {1: [(1, 1), (7, 7)], 2: [(2, 3), (8, 9)], 3: [(4, 6), (10, 12)]})
您现在可以根据需要设置endpoints
字典的输出格式。
顺便说一下,我对你在这个问题中使用“set”感到很困惑,这就是我使用“partition”的原因。
答案 1 :(得分:0)
我对此并不满意,但我确实得到了一份有效的计划。如果有人能够提出更好的答案,我会乐意接受它。
import argparse, sys
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Take a number of pages, and the pages in several sets, to produce an output for copy and paste into the print file downloader', version='%(prog)s 2.0')
parser.add_argument('pages', type=int, help='Total number of pages to break into sets')
parser.add_argument('stapleset', nargs='+', type=int, help='number of pages in each set')
args = parser.parse_args()
data = {}
for c,s in enumerate(args.stapleset):
data[c] = []
currPage = 0
while currPage <= args.pages:
for c,s in enumerate(args.stapleset):
if currPage + 1 > args.pages:
pass
elif currPage + s > args.pages:
data[c].append((currPage+1,args.pages))
else:
data[c].append((currPage+1,currPage+s))
currPage = currPage + s
for key in sorted(data.iterkeys()):
for c,t in enumerate(data[key]):
if c > 0:
sys.stdout.write(",")
sys.stdout.write("{0}-{1}".format(t[0],t[1]))
sys.stdout.write("\n\n")