Python: получить количество элементов в генераторе без сохранения элементов - PullRequest
5 голосов
/ 30 июня 2010

У меня есть генератор для большого набора предметов.Я хочу перебрать их один раз, вывести их в файл.Однако, с форматом файла, который у меня есть в настоящее время, я сначала должен вывести количество элементов, которые у меня есть.Я не хочу составлять список элементов в памяти, так как их слишком много, и это заняло бы много времени и памяти.Есть ли способ выполнить итерацию по генератору, получить его длину, но каким-то образом иметь возможность повторить его позже, получив те же элементы?

Если нет, какое еще решение я мог бы предложить для этой проблемы?

Ответы [ 3 ]

5 голосов
/ 30 июня 2010

Это не может быть сделано. После того, как генератор исчерпан, его необходимо восстановить, чтобы снова использовать. Можно определить метод __len__() для объекта итератора, если число элементов известно заранее, а затем для объекта итератора можно вызвать len().

5 голосов
/ 30 июня 2010

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

В качестве альтернативы, вы можете записать фиктивный размер в ваш файл, записать элементы и затем снова открыть файлизмените и исправьте размер в заголовке.

Если ваш файл представляет собой двоичный формат, это может работать довольно хорошо, так как количество байтов для размера одинаково, независимо от того, каков фактический размер.Если это текстовый формат, возможно, вам придется добавить некоторую дополнительную длину в файл, если вы не смогли дополнить фиктивный размер, чтобы охватить все случаи.См. этот вопрос для обсуждения вставки и перезаписи в текстовый файл с использованием Python.

5 голосов
/ 30 июня 2010

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

Включите генератор здесь, и мы постараемся сделать это для вас!

...