Comment puis-je retourner deux valeurs d'une fonction en Python?

195

Je voudrais retourner deux valeurs d'une fonction dans deux variables distinctes. Par exemple:

def select_choice():
    loop = 1
    row = 0
    while loop == 1:
        print('''Choose from the following options?:
                 1. Row 1
                 2. Row 2
                 3. Row 3''')

        row = int(input("Which row would you like to move the card from?: "))
        if row == 1:
            i = 2
            card = list_a[-1]
        elif row == 2:
            i = 1
            card = list_b[-1]
        elif row == 3:
            i = 0
            card = list_c[-1]
        return i
        return card

Et je veux pouvoir utiliser ces valeurs séparément. Quand j'ai essayé de l'utiliser return i, card, ça renvoie un tupleet ce n'est pas ce que je veux.

Lycon
la source
Veuillez fournir un exemple d'appel de cette fonction attendue et d'utilisation de sa ou ses valeurs de retour, afin de bien comprendre pourquoi vous ne voulez pas de tuples.
bereal
2
Quel est l'intérêt de la boucle while?
Sven Marnach
devrait avoir un else: continueavant les déclarations de retour
machine désirant
Oui, je viens également de remarquer qu'il s'agit d'un doublon de stackoverflow.com/questions/38508/…
lpapp

Réponses:

399

Vous ne pouvez pas retourner deux valeurs, mais vous pouvez retourner un tupleou un listet le décompresser après l'appel:

def select_choice():
    ...
    return i, card  # or [i, card]

my_i, my_card = select_choice()

En ligne return i, card i, cardsignifie créer un tuple. Vous pouvez également utiliser des parenthèses comme return (i, card), mais les tuples sont créés par des virgules, les parenthèses ne sont donc pas obligatoires. Mais vous pouvez utiliser des parens pour rendre votre code plus lisible ou pour diviser le tuple sur plusieurs lignes. La même chose s'applique à la ligne my_i, my_card = select_choice().

Si vous souhaitez renvoyer plus de deux valeurs, pensez à utiliser un tuple nommé . Cela permettra à l'appelant de la fonction d'accéder aux champs de la valeur retournée par son nom, qui est plus lisible. Vous pouvez toujours accéder aux éléments du tuple par index. Par exemple, dans la Schema.loadsméthode, le framework Marshmallow renvoie un UnmarshalResultqui est un namedtuple. Vous pouvez donc faire:

data, errors = MySchema.loads(request.json())
if errors:
    ...

ou

result = MySchema.loads(request.json())
if result.errors:
    ...
else:
    # use `result.data`

Dans d'autres cas, vous pouvez renvoyer un dictde votre fonction:

def select_choice():
    ...
    return {'i': i, 'card': card, 'other_field': other_field, ...}

Mais vous voudrez peut-être envisager de renvoyer une instance d'une classe utilitaire, qui encapsule vos données:

class ChoiceData():
    def __init__(self, i, card, other_field, ...):
        # you can put here some validation logic
        self.i = i
        self.card = card
        self.other_field = other_field
        ...

def select_choice():
    ...
    return ChoiceData(i, card, other_field, ...)

choice_data = select_choice()
print(choice_data.i, choice_data.card)
warvariuc
la source
26

Je voudrais retourner deux valeurs d'une fonction dans deux variables distinctes.

À quoi vous attendriez-vous qu'il ressemble du côté appelant? Vous ne pouvez pas écrire a = select_choice(); b = select_choice()car cela appelerait la fonction deux fois.

Les valeurs ne sont pas renvoyées "dans les variables"; ce n'est pas ainsi que Python fonctionne. Une fonction renvoie des valeurs (objets). Une variable n'est qu'un nom pour une valeur dans un contexte donné. Lorsque vous appelez une fonction et attribuez la valeur de retour quelque part, ce que vous faites est de donner un nom à la valeur reçue dans le contexte d'appel. La fonction ne met pas la valeur "dans une variable" pour vous, l'affectation le fait (peu importe que la variable ne soit pas "stockage" pour la valeur, mais encore une fois, juste un nom).

Quand j'ai essayé de l'utiliser return i, card, il renvoie un tupleet ce n'est pas ce que je veux.

En fait, c'est exactement ce que vous voulez. Tout ce que vous avez à faire est de tupledémonter à nouveau.

Et je veux pouvoir utiliser ces valeurs séparément.

Il suffit donc de saisir les valeurs de la tuple.

La façon la plus simple de procéder consiste à déballer:

a, b = select_choice()
Karl Knechtel
la source
1
Merci d'avoir expliqué "pourquoi c'est comme ça". Meilleure réponse imo.
Edward Coelho
17

Je pense que ce que tu veux, c'est un tuple. Si vous utilisez return (i, card), vous pouvez obtenir ces deux résultats en:

i, card = select_choice()
heinrich5991
la source
8
def test():
    ....
    return r1, r2, r3, ....

>> ret_val = test()
>> print ret_val
(r1, r2, r3, ....)

vous pouvez maintenant faire tout ce que vous voulez avec votre tuple.

Amin Jalali
la source
5
def test():
    r1 = 1
    r2 = 2
    r3 = 3
    return r1, r2, r3

x,y,z = test()
print x
print y
print z


> test.py 
1
2
3
user8541092
la source
2

Et ceci est une alternative.Si vous retournez en tant que liste, il est simple d'obtenir les valeurs.

def select_choice():
    ...
    return [i, card]

values = select_choice()

print values[0]
print values[1]
praveen
la source
2

tu peux essayer ça

class select_choice():
    return x, y

a, b = test()
samuel161
la source
1

Vous pouvez également renvoyer plusieurs valeurs à l'aide de list. Vérifiez le code ci-dessous

def newFn():    #your function
  result = []    #defining blank list which is to be return
  r1 = 'return1'    #first value
  r2 = 'return2'    #second value
  result.append(r1)    #adding first value in list
  result.append(r2)    #adding second value in list
  return result    #returning your list

ret_val1 = newFn()[1]    #you can get any desired result from it
print ret_val1    #print/manipulate your your result
kaushik karan
la source