简体   繁体   English

itertools.combinations:在间隔内多次使用

[英]itertools.combinations: Consume multiple times over intervals

from itertools import combinations
from more_itertools import consume

k = 170
index_list = [16, 32, 48, 62, 76, 88, 100, 110, 120, 128, 136, 142, 148, 153, 158, 161, 164, 166]

for n in range(1, k+1):
    iterable = combinations(range(k), n)
    for output in iterable:
        print(output)

I am having iterables and a list containing indexes as shown above: The index_list is representing intervals: they go from 0 to 16, from 17 to 32, from 33 to 48 and so on.我有可迭代对象和包含如上所示索引的列表: index_list 表示间隔:它们 go 从 0 到 16,从 17 到 32,从 33 到 48 等等。 Last interval is 167 to k-1.最后一个区间是 167 到 k-1。 When I loop a iterable, I want to skip multiple steps, whenever there are 2 values of the output within the same interval.当我循环一个迭代时,我想跳过多个步骤,只要 output 在同一时间间隔内有 2 个值。 Output (0, 1), for example: Both values are within the interval 0-16, so next output shall be (0, 17). Output (0, 1),例如:两个值都在 0-16 的区间内,所以接下来的 output 应该是 (0, 17)。 The outputs afterwards would be (0, 18), (0, 19),..., (0, k-1) as these are not within a interval.之后的输出将是 (0, 18), (0, 19),..., (0, k-1),因为它们不在一个区间内。 Afterwards, the output will be (1, 2) which shall be skipped again and so on.之后,output 将是 (1, 2) 应再次跳过,依此类推。 And later, when the output is (17, 18) it shall skip to (17, 33).稍后,当 output 为 (17, 18) 时,它应跳至 (17, 33)。 When n is 3, the very first output is (0, 1, 2) which then shall be skipped to (0, 17, 33).当 n 为 3 时,第一个 output 为 (0, 1, 2),然后应跳至 (0, 17, 33)。 The consume-method provided by more-itertools allows one to step multiple elements ahead. more-itertools 提供的消费方法允许一个人前进多个元素。 Here it would be used like so:在这里它会像这样使用:

consume(iterable, 20)    # skipping 20 steps ahead

I have managed it to get the wanted behavior for 2 elements in the output:我已经设法获得 output 中 2 个元素的所需行为:

steps = 0
for i, out in enumerate(output):
    for j, index in enumerate(index_list):
        if out <= index:
            break
    try:
        if output[i + 1] <= index_list[j]:
            steps = steps + index_list[j] - output[i + 1]
    except:
        pass
consume(iterable, steps)

But for 3 elements and more the amount of steps is not calculated correctly anymore.但是对于 3 个或更多元素,不再正确计算步数。 It must be multiplied by some value but I don't know where to get it.它必须乘以某个值,但我不知道从哪里得到它。 Another task is, that I do not want to check for the intervals for every single output.另一个任务是,我不想检查每个 output 的间隔。 When a consume was executed, it somehow must already know when the next consume-instruction will happen.当执行消费时,它必须以某种方式已经知道下一个消费指令何时发生。 Any help please?请问有什么帮助吗?

This code only works when n < 20 (Because the number of statically nested blocks in Python is limited to 20 )此代码仅在 n < 20 时有效(因为 Python 中的静态嵌套块数限制为 20

k = 170
index_list = [16, 32, 48, 62, 76, 88, 100, 110, 120, 128, 136, 142, 148, 153, 158, 161, 164, 166]


def get_bound(x):
    for i in range(len(index_list)):
        if x <= index_list[i]:
            return index_list[i]
    return k


def valid_combs(i, n=None, comb=None):
    n = n if n is not None else i
    comb = comb or list(range(n))
    if i == n:
        for x in range(k):
            comb[0] = x
            yield from valid_combs(i - 1, n, comb)
    elif i >= 1:
        prev = comb[n - i - 1]
        bound = get_bound(prev)
        for x in list(range(bound + 1, k)):
            comb[n - i] = x   
            yield from valid_combs(i - 1, n, comb)
    else:
        yield tuple(comb)


for n in range(1, k+1):
    iterable = valid_combs(n)
    for output in iterable:
        print(output)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM