День! решая пришлось найти в сети алгоритм поиска всех делителей числа. ну то есть для восьми надо выдать [1,2,4,8], а не [2,2,2] - список делителей. Я переписал этот алгоритм наново, прошу ""старших товарищей"" подсказать как улучшить. Если есть время ))
def divisorss(n): from collections import Counter ls = get_ls(n) # for n=1568 -> ls = [2, 2, 2, 2, 2, 7, 7] pairs = dict(Counter(ls)) # {2: 5, 7: 2} from itertools import product, starmap from operator import mul from functools import reduce # список всех различных делитей числа bases = [b for b in pairs.keys()] # [2, 7] # список степеней, в которые возводятся уникальные делители для получения числа powers = [[i for i in range(k+1)] for k in pairs.values()] # генерирование всех наборов для получения делителей исходного числа multi = product(*powers) # сцепка списка оснований с возможными вариантами степеней wrk = (zip(bases,power) for power in multi) # наборы чисел, которые нужно перемножить для получения делителя rezzz = (starmap( pow, row) for row in wrk) # возвращение списка всех делителей retu [reduce(mul,i) for i in rezzz]например divisorss(1568) возвращает [1, 7, 49, 2, 14, 98, 4, 28, 196, 8, 56, 392, 16, 112, 784, 32, 224, 1568]
Функция get_ls(n) дает соответственно список разложения числа на произведение делителей
например такая:
def get_ls(n): """"""Разложить число на множители"""""" #result = [1] result = [] i = 2 while i*i <= n: if n % i == 0: n //= i result.append(i) else: i += 1 if n > 1: result.append(n) retu resultчто можно улучшить?
Ну например, что лучше - reduce из functools или accumulate из itertools. Ну и вообще по алгоритму.
Понятно, что улучшения типа
retu [reduce(mul,i) for i in (starmap(pow, row) for row in (zip(bases,power) for power in product(*powers)))] не интересны.
question@mail.ru
·