Я пытаюсь использовать функции itertools.combinations
и itertools.slice
, чтобы создать ряд пакетов, для которых вычисления могут выполняться параллельно. Я использую следующую функцию для создания своих партий:
def construct_batches(n,k,batch_size):
combinations_slices = []
# Calculate number of batches
n_batches = math.ceil(comb(n,k,exact=True)/batch_size)
# Construct iterator for combinations
combinations = itertools.combinations(range(n),k)
while len(combinations_slices) < n_batches:
combinations_slices.append(itertools.islice(combinations,batch_size))
return combinations_slices
После выполнения некоторых вычислений я выясняю, какие партии и элементы актуальны. Таким образом, у меня есть список пакетов (например, batches = [2,3,1]
) и список элементов (например, elements = [5,7,0]
). К моему изумлению / ужасу питон имеет следующее поведение. Предположим, я хочу проверить, правильны ли мои кусочки. Тогда
combinations_slices = construct_batches(n,k,batch_size)
list(combinations_slices[0])
Out[491]:
[(0, 1, 2, 3),
(0, 1, 2, 4),
(0, 1, 2, 5),
(0, 1, 2, 6),
(0, 1, 2, 7),
(0, 1, 2, 8),
(0, 1, 2, 9),
(0, 1, 3, 4),
(0, 1, 3, 5),
(0, 1, 3, 6)]
list(combinations_slices[1])
Out[492]:
[(0, 1, 3, 7),
(0, 1, 3, 8),
(0, 1, 3, 9),
(0, 1, 4, 5),
(0, 1, 4, 6),
(0, 1, 4, 7),
(0, 1, 4, 8),
(0, 1, 4, 9),
(0, 1, 5, 6),
(0, 1, 5, 7)]
Это все мило и весело, показывает, что подход сработал. Однако, если я использую понимание списка, чтобы выбрать «соответствующие» партии как combinations_slices = [combinations_slices[i] for i in range(len(combinations_slices)) if i in batches]
, то результат будет (к сожалению):
combinations_slices = construct_batches(n,k,batch_size)
batches = [2,3,1]
combinations_slices = [combinations_slices[i] for i in range(len(combinations_slices)) if i in batches]
list(combinations_slices[0])
Out[509]:
[(0, 1, 2, 3),
(0, 1, 2, 4),
(0, 1, 2, 5),
(0, 1, 2, 6),
(0, 1, 2, 7),
(0, 1, 2, 8),
(0, 1, 2, 9),
(0, 1, 3, 4),
(0, 1, 3, 5),
(0, 1, 3, 6)]
list(combinations_slices[1])
Out[510]:
[(0, 1, 3, 7),
(0, 1, 3, 8),
(0, 1, 3, 9),
(0, 1, 4, 5),
(0, 1, 4, 6),
(0, 1, 4, 7),
(0, 1, 4, 8),
(0, 1, 4, 9),
(0, 1, 5, 6),
(0, 1, 5, 7)]
Есть ли способ получить желаемое поведение, не приводя все к спискам (как правило, эти списки комбинаций могут быть большими, так что мне не хватит памяти ...)? Предложения приветствуются ...