Как заставить itertools.permutations () записывать каждый пример в файл, изменяя код - Python

Это код itertools.permutations:

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = list(range(n))
    cycles = list(range(n, n-r, -1))
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

Я хочу, чтобы вместо добавления перестановок в список он сразу записывал каждую перестановку, которую он находит, в файл .txt, а не зацикливал список и записывал их в файл.

Почему бы не записать результат использования функции в файл?

mkrieger1 18.11.2018 16:54

ОК, круто. Что вам мешает сделать это? Вы умеете открывать файлы? Ты умеешь им писать? Пожалуйста, прочтите Как спросить.

Chris 18.11.2018 16:55

Я умею открывать и записывать файлы.

Johnny P. 18.11.2018 16:56

@PatrickArtner Это будет не то же самое, если r == 0.

mkrieger1 18.11.2018 16:57

код - copy&paste от docs.python.org/3/library/itertools.html#itertools.permutati‌ ons ... что вы кодировали?

Patrick Artner 18.11.2018 16:58

@ mkrieger1 hoppla - ты прав ... r = 0 не имеет никакого смысла - но он должен возвращать [], а не их perms of n.

Patrick Artner 18.11.2018 16:58

Я не знаю, но я думаю, что разработчики Python знали, что они делали.

mkrieger1 18.11.2018 17:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
6
7
435
1

Ответы 1

Вся суть itertools в том, что значения создаются лениво, а не в виде списков. Вам не нужно менять код permutations, все, что вам нужно сделать, это перебрать перестановки как они производятся и затем записать их в файл.

for p in permutations(your_iterable):
    # your code to write p to a file here

Обратите внимание, что в этом коде нет списка. permutations(your_iterable) - это итератор, из которого можно явно извлекать значения с помощью next или неявно, используя цикл for.

it is a very large amount of permutations and causes a memory error

Я пытаюсь сказать вам, что permutations(your_iterable) никогда не может вызвать ошибку памяти в любом неискусственно надуманном сценарии, если вы сами явно не составите список из permutations(your_iterable). Итератор производит перестановку один за раз, которую вы можете записать в файл, никогда не сохраняя все перестановки в ОЗУ.

I am passing a list of length 110 to itertools.permuations

Это не проблема стандартной библиотеки или значений в ОЗУ.

Ваш код будет производить

15882455415227429404253703127090772871724410234473563207581748318444567162948183030959960131517678520479243672638179990208521148623422266876757623911219200000000000000000000000000

перестановки. На планете нет файловой системы с достаточным объемом памяти для записи этих перестановок.

Кроме того, до тепловой смерти Вселенной не осталось времени, чтобы вычислить все эти перестановки, даже если бы вы могли вычислить их за наносекунду.

>>> from math import factorial
>>> factorial(110)/(10E9*3600*24*365)
>>> 5.0362935740827724e+160 # years

4 is the second parameter for permutations

Хорошо, в этом случае вашему файлу потребуется около 1,7 ГиБ места, если вы сохраните каждую перестановку в виде строки минимальной длины 13, подобной '(0, 1, 2, 3)\n', с одним байтом на символ.

>>> perms = sum(1 for _ in permutations(list(range(110)), 4))
>>> perms*13/(2**30)
>>> 1.677529625594616

Это выполнимо, но для этого может потребоваться гораздо больше места, если объекты в вашем списке имеют более длинные строковые представления. Мы не можем сказать вам, почему вы получаете ошибку памяти, не видя своего кода.

Я хочу писать их, когда они производятся не зацикливанием.

Johnny P. 18.11.2018 16:59

@JohnnyP. этот код записывает каждую перестановку в файл, как только она создается. «Не зацикливать» здесь не имеет смысла, у вас должен быть где-то цикл, если вы хотите делать то же самое (писать) для множества других вещей (перестановок).

timgeb 18.11.2018 17:00

@JohnnyP., Похоже, это XY проблема. Почему вы озабочены тем, есть ли петля или нет? Чего вы пытаетесь достичь фактически?

Chris 18.11.2018 17:04

@JohnnyP. stackoverflow.com/questions/1756096/…

mkrieger1 18.11.2018 17:04

Потому что это очень большое количество перестановок и вызывает ошибку памяти.

Johnny P. 18.11.2018 17:05

@JohnnyP., Тогда вы должны написать ваш код и спросить о ошибка памяти. Это не проблема кода стандартной библиотеки Python, это проблема кода ваш.

Chris 18.11.2018 17:08

Он возвращает ошибку памяти, потому что существуют миллиарды перестановок.

Johnny P. 18.11.2018 17:09

@JohnnyP., А не из-за кода, о котором вы спрашиваете. Это проблема с тем, как вы используете стандартную библиотеку, которую вы нам не показываете.

Chris 18.11.2018 17:09

@JohnnyP. хорошо ли на вашем жестком диске достаточно места для миллиардов перестановок? ...

timgeb 18.11.2018 17:09

Сколько места мне нужно?

Johnny P. 18.11.2018 17:11

... как мы знать, сколько места вам нужно? Опять же, вам не показал нам что-либо полезно разобраться в вашей проблеме. Покажите нам код ваш, расскажите о своем наборе данных, спросите об ошибке памяти, и тогда, возможно, мы сможем вам помочь.

Chris 18.11.2018 17:12

@timgeb вы написали: «Итератор производит одну перестановку за раз, которую вы можете записать в файл, никогда не сохраняя все перестановки в ОЗУ». Но как?

Johnny P. 18.11.2018 17:12

Я использую itertools.permutations (список длиной 110, 4)

Johnny P. 18.11.2018 17:14

@JohnnyP., Я скажу это еще раз, а потом уйду. Вы должен показываете нам актуальный код ваш. "Список длиной 110, 4" не имеет смысла. Списки бывают одной длины, а не двух. Вы действительно что-то делаете с массивами numpy? Мы буквально не может вам поможет, как вы спрашиваете. Проблема не в стандартной библиотеке. Прочтите Как спросить и попробуйте еще раз.

Chris 18.11.2018 17:16

4 - второй параметр для перестановок.

Johnny P. 18.11.2018 17:18

@JohnnyP. "но как" <- производя значения "на лету", а не в виде списков. Если вы хотите узнать, как реализованы итераторы, не стесняйтесь читать исходный код CPython.

timgeb 18.11.2018 17:19

@JohnnyP. знаете ли вы, что пытаетесь хранить факториальные (110) перестановки?

timgeb 18.11.2018 17:32

@timgeb Второй параметр перестановки - 4, поэтому я хочу сохранить 110 * 109 * 108 * 107.

Johnny P. 18.11.2018 18:00

Другие вопросы по теме