web-dev-qa-db-fra.com

comprendre la liste pour la fonction de retour multiple?

J'ai une fonction qui renvoie deux valeurs et j'aimerais utiliser une liste de compréhension pour remplir deux listes. par exemple:

def f(x):
  return 2*x,x*x

x = range(3)
xlist, ylist = [f(value) for value in x]

EDITS from answers below:
xtuple, ytuple = Zip(*[f(value) for value in x])
xlist, ylist = map(list,Zip(*[f(value) for value in x]))

où le rendement attendu devrait être:

xlist = [0, 2, 4]
ylist = [0, 1, 4]

ma question se résume à:

Actuellement, je reçois une liste de n-uplets, bien que ce soit raisonnable, il me faudra deux listes indépendantes. actuellement, je pourrais avoir une variable de marque de réservation (liste de tuples) et 3 compréhensions totales. Mais je me demande s’il existe un moyen propre de le faire avec une compréhension de liste unique.

A noter: dans le code réel, mes deux déclarations sont corrélées, je ne peux donc pas simplement scinder la fonction en deux.

8
Christophe

Tout d’abord, vous avez commis une petite erreur: cela devrait être:

[f(value) for value in x]
#  ^ notice the `value`

au lieu de:

[f(x) for value in x]

De plus, le fait est que:

return 2*x,x

est l'abréviation de:

return (2*x,x)

alors un tuple} _. Votre compréhension de liste donc génère une liste de tuples _, pas un tuple de listes. La bonne chose de Zip cependant est que vous pouvez facilement l'utiliser à l'envers avec l'astérisque:

xlist,ylist = Zip(*[f(value) for value in x])
#                 ^ with asterisk

Notez que xlist

qui se traduit par:

>>> xlist
[0, 2, 4]
>>> ylist
[0, 1, 4]

(notez que ranges commence à compter à partir de 0)

Alternative: Une autre façon de faire est bien sûr:

xlist = [f(value)[0] for value in x]
ylist = [f(value)[1] for value in x]

Mais ceci est bien sûr inelegantly et peut en outre être inefficace (étant donné que f est coûteux en calcul).

12
Willem Van Onsem

Utilisez la fonction intégrée Zip() ,

def f(x):
  return 2*x, x*x

x = range(1, 4)
xlist, ylist = Zip(*[f(value) for value in x])

print(xlist, ylist)
# ((2, 4, 6), (1, 4, 9))
5
SparkAndShine

Faisons ce travail. La fonction est bien:

def f(x):
  return 2*x, x*x

Mais vous voulez définir la plage comme suit, notez les valeurs de début et de fin:

x = range(1, 4)

De plus, vous devez appeler la fonction avec le paramètre value , pas avec le paramètre list . Et l'astuce finale pour décompresser le résultat en deux listes, consiste simplement à Zip(*lst) le résultat de la compréhension de la liste:

xlist, ylist = Zip(*[f(value) for value in x])

Maintenant, le résultat est comme prévu:

xlist 
=> [2, 4, 6]
ylist 
=> [1, 4, 9]
5
Óscar López

Utilisation 

Zip(*your_list_of_bituples)

Exemple

demo_list = [(1, 2), (2, 3), (4, 5)]
Zip(*demo_list)

Va donner

[(1, 2, 4), (2, 3, 5)]
3
Elmex80s

Je sais qu'il est tard mais ce qui suit donne ce que vous voulez.

def f(value):
    xlist = []
    ylist = []
    for x, y in [(2*x, x*x) for x in range(value)]:
        xlist.append(x)
        ylist.append(y)
    return xlist, ylist

x = int(input("enter a value: "))
xval, yval = f(x)

print(f"xlist = {xval}\nylist = {yval}")
0
K. Solowoniuk