Как клонировать объект генератора Python?
Рассмотрим этот сценарий:
#! / usr / bin / env python # - * - кодирование: utf-8 - * - import os walk = os.walk ('/ home') для root, dirs, файлов в пути: для имени пути в файлах dirs +: print os.path.join (root, pathname) для root, dirs, файлов в пути: для имени пути в файлах dirs +: print os.path.join (root, pathname)
Я знаю, что этот пример является излишним, но вы должны учитывать, что нам нужно использовать одни и те же данные walk
более одного раза. У меня есть эталонный сценарий, и использование одинаковых данных walk
является обязательным для получения полезных результатов.
- Класс вектора Python
- Ошибка компилятора Python, x не принимает аргументов (1 данный)
- Python Django: лучше ли добавлять свойства к объекту или делать словарь данных?
- TensorFlow Object Detection API отображает объекты, найденные на изображении, на консоли
- В python есть ли способ узнать, реализует ли объект «реализует интерфейс», прежде чем передать его функции?
Я пробовал walk2 = walk
к клону и использовать на второй итерации, но это не сработало. Вопрос … Как я могу его скопировать? Возможно ли это?
Заранее спасибо.
- python: изменение печати класса
- Создание PASCAL Voc для API обнаружения объектов Tensorflow
- Почему Python не вызывает метод экземпляра __init __ () при создании экземпляра, но вызывает вместо него класс __init __ ()?
- Каков прецедент для метода __new__ для возврата объекта другого типа, чем его первый аргумент?
- AttributeError: объект 'property' не имеет атрибута
4 Solutions collect form web for “Как клонировать объект генератора Python?”
Вы можете использовать itertools.tee()
:
walk, walk2 = itertools.tee(walk)
Обратите внимание, что это может «потребовать значительного дополнительного хранения», как указано в документации.
Если вы знаете, что собираетесь перебирать весь генератор для каждого использования, вы, вероятно, получите максимальную производительность, развернув генератор в список и используя список несколько раз.
walk = list(os.walk('/home'))
Определить функцию
def walk_home(): for r in os.walk('/home'): yield r
Или даже это
def walk_home(): return os.walk('/home')
Оба используются следующим образом:
for root, dirs, files in walk_home(): for pathname in dirs+files: print os.path.join(root, pathname)
Этот ответ направлен на расширение / уточнение того, что высказали другие ответы. Решение обязательно будет зависеть от того , чего именно вы стремитесь достичь.
Если вы хотите os.walk
один и тот же результат os.walk
несколько раз, вам нужно будет инициализировать список из os.walk
os.walk iterable (т. os.walk
Walk walk = list(os.walk(path))
).
Если вы должны гарантировать, что данные остаются теми же, это, вероятно, ваш единственный вариант. Однако существует несколько сценариев, в которых это невозможно или желательно.
- Невозможно
list()
итерабельность, если выход имеет достаточный размер (т. Е. Попыткаlist()
вся файловая система может заморозить ваш компьютер). - Нежелательно
list()
итерируемый, если вы хотите получить «свежие» данные перед каждым использованием.
Если list()
не подходит, вам нужно будет запустить генератор по требованию. Обратите внимание, что генераторы гасятся после каждого использования, поэтому это создает небольшую проблему. Чтобы «повторно запустить» ваш генератор несколько раз, вы можете использовать следующий шаблон:
#!/usr/bin/env python # -*- coding: utf-8 -*- import os class WalkMaker: def __init__(self, path): self.path = path def __iter__(self): for root, dirs, files in os.walk(self.path): for pathname in dirs + files: yield os.path.join(root, pathname) walk = WalkMaker('/home') for path in walk: pass # do something... for path in walk: pass
Вышеупомянутый шаблон дизайна позволит вам сохранить код DRY.
- Python: обмен глобальными переменными между модулями и классами в нем
- Колба разбитая труба с запросами