Как я могу вернуть два значения из функции в Python?

195

Я хотел бы вернуть два значения из функции в двух отдельных переменных. Например:

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

И я хочу иметь возможность использовать эти значения отдельно. Когда я пытался использовать return i, card, он возвращает, tupleи это не то, что я хочу.

Lycon
источник
Пожалуйста, приведите пример вызова этой ожидаемой функции и использования ее возвращаемых значений, чтобы было понятно, почему вам не нужны кортежи.
bereal
2
Какой смысл цикла while?
Свен Марнах
должно быть else: continueдо возвращения заявления
машина тоскует
Да, я только что заметил , что это дубликат stackoverflow.com/questions/38508/...
lpapp

Ответы:

399

Вы не можете вернуть два значения, но вы можете вернуть a tupleили a listи распаковать его после вызова:

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

my_i, my_card = select_choice()

На линии return i, card i, cardозначает создание кортежа. Вы также можете использовать круглые скобки return (i, card), но кортежи создаются через запятую, поэтому парены не обязательны. Но вы можете использовать парены, чтобы сделать ваш код более читабельным или разбить кортеж на несколько строк. То же самое относится и к линии my_i, my_card = select_choice().

Если вы хотите вернуть более двух значений, рассмотрите возможность использования именованного кортежа . Это позволит вызывающей функции получить доступ к полям возвращаемого значения по имени, которое более читабельно. Вы по-прежнему можете получить доступ к элементам кортежа по индексу. Например, в Schema.loadsметоде Marshmallow Framework возвращает a, UnmarshalResultкоторый является a namedtuple. Так что вы можете сделать:

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

или

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

В других случаях вы можете вернуть dictиз вашей функции:

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

Но вы можете рассмотреть возможность возврата экземпляра служебного класса, который упаковывает ваши данные:

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
источник
27

Я хотел бы вернуть два значения из функции в двух отдельных переменных.

Как вы ожидаете, что это будет выглядеть на вызывающей стороне? Вы не можете написать, a = select_choice(); b = select_choice()потому что это вызвало бы функцию дважды.

Значения не возвращаются "в переменных"; это не то, как работает Python. Функция возвращает значения (объекты). Переменная - это просто имя для значения в данном контексте. Когда вы вызываете функцию и присваиваете возвращаемое значение где-то, вы делаете, что присваиваете полученному значению имя в контексте вызова. Функция не помещает значение «в переменную» для вас, присваивание делает (не говоря уже о том, что переменная не является «хранилищем» для значения, но опять же, просто имя).

Когда я пытался использовать return i, card, он возвращает, tupleи это не то, что я хочу.

На самом деле, это именно то, что вы хотите. Все, что вам нужно сделать, это tupleснова разобрать.

И я хочу иметь возможность использовать эти значения отдельно.

Так что просто возьмите значения из tuple.

Самый простой способ сделать это - распаковать:

a, b = select_choice()
Карл Кнехтель
источник
1
Спасибо за объяснение "почему это так". Лучший ответ IMO.
Эдвард Коэльо
17

Я думаю, что ты хочешь, это кортеж. Если вы используете return (i, card), вы можете получить эти два результата:

i, card = select_choice()
heinrich5991
источник
8
def test():
    ....
    return r1, r2, r3, ....

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

Теперь вы можете делать все, что вам нравится с вашим кортежем.

Амин Джалали
источник
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
источник
2

И это альтернатива. Если вы возвращаетесь в виде списка, то получить значения просто.

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

values = select_choice()

print values[0]
print values[1]
Praveen
источник
2

ты можешь попробовать это

class select_choice():
    return x, y

a, b = test()
samuel161
источник
1

Вы также можете вернуть более одного значения, используя список. Проверьте код ниже

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
Каушик Каран
источник