TheMaxai
@TheMaxai

Как разбить на части распараллеливание списка?

Нужно взять список допустим
list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Разбить на 3 части
И нужно чтобы получилось 3 списка(Но список разной длины, поэтому не всегда 3)
И потом выполнить определенную операцию со списками,
например умножить элемент из списка на 2. Но сделать это нужно параллельно.
Потом нужно совместить результаты. В итоге получится
[2, 4, 6, 8, 10, 12, 14, 16, 18]
Я как то пытался создавать динамические переменные и после их использовать,
но к сожалению у меня не чего не вышло
  • Вопрос задан
  • 338 просмотров
Решения вопроса 2
@trofimovdev
Python
Для обработки данных в несколько процессов существует multiprocessing с замечательной функцией map (не путать с обычным map).
from multiprocessing import *

def func(e):
	return e ** 2
	
p = Pool(4) # количество процессов
end = p.map(func, [2, 4, 6, 8, 16])
print(end)
>> [4, 16, 36, 64, 256]


Данный код создает 4 процесса, каждый из которых делает следующее:
  1. Берет i-ный элемент из начального списка (для первого процесса: 1, 5, 9; для второго: 2, 6, 10; для третьего: 3, 7, 11 и т.д.)
  2. Передает его в функцию func
  3. Получает результат из func
  4. Вставляет в новый список на i-ное место этот элемент


Прошу заметить, что хоть разные элементы списка обрабатываются в разное время (это легко понять, добавив в функцию print(e)), но в конечном списке они соблюдают начальную последовательность.
Ответ написан
@skozlovf
Реализаций можно написать много.

Вариант 1: google "python split list into chunks"

Вариант 2: если в проекте используется numpy:

import numpy as np

def split(seq, num_chunks):
    lst = np.array_split(np.array(seq), num_chunks)
    return [x.tolist() for x in lst if len(x)]


Вариант 3 (только сейчас придумал, для py 2):

from __future__ import division
import math

def split(seq, num_chunks):
    assert num_chunks
    pos = 0
    sz = len(seq)
    result = []
    while pos < sz:
        num_items = int(math.ceil((sz - pos) / num_chunks))
        result.append(seq[pos:pos + num_items])
        pos = pos + num_items
        num_chunks -= 1
    return result


split([1, 2, 3, 4, 5, 6, 7, 8, 9], X)

# X
# 1   [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
# 2   [[1, 2, 3, 4, 5], [6, 7, 8, 9]]
# 3   [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 4   [[1, 2, 3], [4, 5], [6, 7], [8, 9]]
# 5   [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
# 6   [[1, 2], [3, 4], [5, 6], [7], [8], [9]]
# 7   [[1, 2], [3, 4], [5], [6], [7], [8], [9]]
# 8   [[1, 2], [3], [4], [5], [6], [7], [8], [9]]
# 9   [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
# 10  [[1], [2], [3], [4], [5], [6], [7], [8], [9]]


Вариант 4 - вариация варианта 3. Теперь split это генератор и всегда возвращает указанное кол-во частей/отрезков
def split(seq, num_chunks):
    assert num_chunks
    pos = 0
    sz = len(seq)
    while pos < sz:
        num_items = int(math.ceil((sz - pos) / num_chunks))
        yield seq[pos:pos + num_items]
        pos = pos + num_items
        num_chunks -= 1

    for _ in range(num_chunks):
        yield []

list(split([1, 2, 3, 4, 5, 6, 7, 8, 9], X))

# X
# ...
# 9   [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
# 10  [[1], [2], [3], [4], [5], [6], [7], [8], [9], []]
# 11  [[1], [2], [3], [4], [5], [6], [7], [8], [9], [], []]


и т. д.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы