J'ai accès à un générateur qui produit deux valeurs :
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']
J'ai une autre fonction, process_x
Je ne peux pas modifier ce système qui peut recevoir un générateur en entrée et qui traite toutes les données de la base de données. x
pour tous les documents (si un tuple est produit, il ne traite que le premier élément du tuple et ignore les autres éléments) :
X = process_x(get_document_values()) # This processes x but ignores y
Cependant, j'ai besoin de stocker tous les y
du générateur. Ma seule solution est d'exécuter get_document_values
deux fois :
Y = [y for x,y in get_document_values()] #Throw away x
X = process_x(get_document_values()) #Throw away y
Cela fonctionne techniquement, mais lorsqu'il y a de nombreux documents à traiter, il est possible qu'un nouveau document soit inséré dans la base de données et que les longueurs de X
et Y
sera différente. Il doit y avoir une correspondance univoque entre X
et Y
et j'aimerais n'avoir qu'à appeler get_document_values
une fois au lieu de deux.
J'ai envisagé quelque chose comme :
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()))
Mais.. :
- Cela ne semble pas pythonique
-
Y
doit être déclarée comme variable globale
J'espère qu'il existe un moyen plus propre et plus pythonique de faire cela.
Mise à jour
En réalité, get_document_values
renverra des valeurs de x
qui sont trop volumineux pour être stockés collectivement dans la mémoire et process_x
réduit en fait cette exigence de mémoire. Il n'est donc pas possible de mettre en cache l'ensemble des x
. La mise en cache de tous les y
est très bien.