Вот один из способов заставить ваш подход работать.Использует itertools.combinations
.Создание полного списка занимает несколько секунд.Для более быстрого подхода на основе numpy
см. Нижнюю часть этого поста.
Он работает путем перечисления всех комбинаций четырех тактов от 1 до 100, всегда добавляя внешние такты от 0 до 101. Распределения для пяти детейтогда что между барами, то есть разность столбцов минус один.
import numpy as np
import itertools
bars = [0, 0, 0, 0, 0, 101]
result = [[bars[j+1] - bars[j] - 1 for j in range(5)] for bars[1:-1] in itertools.combinations(range(1, 101), 4)]
# sanity check
len(result)
# 3921225
# show few samples
from pprint import pprint
pprint(result[::400000])
# [[0, 0, 0, 0, 96],
# [2, 26, 12, 8, 48],
# [5, 17, 22, 7, 45],
# [8, 23, 30, 16, 19],
# [12, 2, 73, 9, 0],
# [16, 2, 25, 40, 13],
# [20, 29, 24, 0, 23],
# [26, 13, 34, 14, 9],
# [33, 50, 4, 5, 4],
# [45, 21, 26, 1, 3]]
Почему у вас не так хорошо работает?Я думаю, в основном потому, что ваш цикл немного расточительный, 97 ^ 5 немного больше, чем 100, выберите 4.
Если вы хотите очень быстро, вы можете заменить itertools.combinations
версией numpy
:
https://stackoverflow.com/a/42202157/7207392
def fast_comb(n, k):
a = np.ones((k, n-k+1), dtype=int)
a[0] = np.arange(n-k+1)
for j in range(1, k):
reps = (n-k+j) - a[j-1]
a = np.repeat(a, reps, axis=1)
ind = np.add.accumulate(reps)
a[j, ind[:-1]] = 1-reps[1:]
a[j, 0] = j
a[j] = np.add.accumulate(a[j])
return a
fb = fast_comb(100, 4)
sb = np.empty((6, fb.shape[1]), int)
sb[0], sb[1:5], sb[5] = -1, fb, 100
result = np.diff(sb.T) - 1
result.shape
# (3921225, 5)
result[::400000]
# array([[ 0, 0, 0, 0, 96],
# [ 2, 26, 12, 8, 48],
# [ 5, 17, 22, 7, 45],
# [ 8, 23, 30, 16, 19],
# [12, 2, 73, 9, 0],
# [16, 2, 25, 40, 13],
# [20, 29, 24, 0, 23],
# [26, 13, 34, 14, 9],
# [33, 50, 4, 5, 4],
# [45, 21, 26, 1, 3]])
Это занимает около одной секунды.