У меня есть доступ к генератору, который выдает два значения:
def get_document_values():
docs = query_database() # returns a cursor to database documents
for doc in docs:
# doc is a dictionary with ,say, {'x': 1, 'y': 99}
yield doc['x'], doc['y']
У меня есть другая функция, process_x
, которую я не могу изменить, которая может принять генератор в качестве входных данных, который обрабатывает все x
для всех документов (если получен кортеж, то он просто обрабатывает первый элемент кортеж и игнорирует другие элементы):
X = process_x(get_document_values()) # This processes x but ignores y
Однако мне нужно также сохранить все значения y
из генератора. Мое единственное решение - выполнить get_document_values
дважды:
Y = [y for x,y in get_document_values()] #Throw away x
X = process_x(get_document_values()) #Throw away y
Технически это работает, но когда нужно обработать много документов, возможно, что новый документ будет вставлен в базу данных, а длины X
и Y
будут другими. Между X
и Y
должно быть взаимно-однозначное сопоставление, и мне нужно было бы вызывать get_document_values
только один раз вместо двух.
Я рассмотрел что-то вроде:
Y = []
def process_y(doc_generator):
global Y
for x,y in doc_generator:
Y.append(y)
yield x
X = process_x(process_y(get_document_values()))
Но:
- Это не кажется питоническим
Y
необходимо объявить как глобальную переменную
Я надеюсь, что есть более чистый, более питонский способ сделать это.
Обновление
На самом деле, get_document_values
будет возвращать значения x
, которые слишком велики для коллективного хранения в памяти, а process_x
фактически уменьшает эту потребность в памяти. Таким образом, невозможно кэшировать все x
. Кэширование всего y
нормально, хотя.