Это код 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, а не зацикливал список и записывал их в файл.
ОК, круто. Что вам мешает сделать это? Вы умеете открывать файлы? Ты умеешь им писать? Пожалуйста, прочтите Как спросить.
Я умею открывать и записывать файлы.
@PatrickArtner Это будет не то же самое, если r == 0.
код - copy&paste от docs.python.org/3/library/itertools.html#itertools.permutati ons ... что вы кодировали?
@ mkrieger1 hoppla - ты прав ... r = 0 не имеет никакого смысла - но он должен возвращать [], а не их perms of n.
Я не знаю, но я думаю, что разработчики Python знали, что они делали.






Вся суть 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
Это выполнимо, но для этого может потребоваться гораздо больше места, если объекты в вашем списке имеют более длинные строковые представления. Мы не можем сказать вам, почему вы получаете ошибку памяти, не видя своего кода.
Я хочу писать их, когда они производятся не зацикливанием.
@JohnnyP. этот код записывает каждую перестановку в файл, как только она создается. «Не зацикливать» здесь не имеет смысла, у вас должен быть где-то цикл, если вы хотите делать то же самое (писать) для множества других вещей (перестановок).
@JohnnyP., Похоже, это XY проблема. Почему вы озабочены тем, есть ли петля или нет? Чего вы пытаетесь достичь фактически?
@JohnnyP. stackoverflow.com/questions/1756096/…
Потому что это очень большое количество перестановок и вызывает ошибку памяти.
@JohnnyP., Тогда вы должны написать ваш код и спросить о ошибка памяти. Это не проблема кода стандартной библиотеки Python, это проблема кода ваш.
Он возвращает ошибку памяти, потому что существуют миллиарды перестановок.
@JohnnyP., А не из-за кода, о котором вы спрашиваете. Это проблема с тем, как вы используете стандартную библиотеку, которую вы нам не показываете.
@JohnnyP. хорошо ли на вашем жестком диске достаточно места для миллиардов перестановок? ...
Сколько места мне нужно?
... как мы знать, сколько места вам нужно? Опять же, вам не показал нам что-либо полезно разобраться в вашей проблеме. Покажите нам код ваш, расскажите о своем наборе данных, спросите об ошибке памяти, и тогда, возможно, мы сможем вам помочь.
@timgeb вы написали: «Итератор производит одну перестановку за раз, которую вы можете записать в файл, никогда не сохраняя все перестановки в ОЗУ». Но как?
Я использую itertools.permutations (список длиной 110, 4)
@JohnnyP., Я скажу это еще раз, а потом уйду. Вы должен показываете нам актуальный код ваш. "Список длиной 110, 4" не имеет смысла. Списки бывают одной длины, а не двух. Вы действительно что-то делаете с массивами numpy? Мы буквально не может вам поможет, как вы спрашиваете. Проблема не в стандартной библиотеке. Прочтите Как спросить и попробуйте еще раз.
4 - второй параметр для перестановок.
@JohnnyP. "но как" <- производя значения "на лету", а не в виде списков. Если вы хотите узнать, как реализованы итераторы, не стесняйтесь читать исходный код CPython.
@JohnnyP. знаете ли вы, что пытаетесь хранить факториальные (110) перестановки?
@timgeb Второй параметр перестановки - 4, поэтому я хочу сохранить 110 * 109 * 108 * 107.
Почему бы не записать результат использования функции в файл?