Pergunta

Say Eu tenho uma função Python que retorna vários valores em uma tupla:

def func():
    return 1, 2

Existe uma boa maneira de ignorar um dos resultados ao invés de apenas atribuir a uma variável temporária? Diga se eu estava interessado apenas no primeiro valor, há uma maneira melhor do que este:

x, temp = func()
Foi útil?

Solução

Uma convenção comum é usar um "_" como um nome de variável para os elementos da tupla você deseja ignorar. Por exemplo:

def f():
    return 1, 2, 3

_, _, x = f()

Outras dicas

Você pode usar x = func()[0] para retornar o primeiro valor, x = func()[1] para retornar o segundo, e assim por diante.

Se você deseja obter vários valores de cada vez, use algo como x, y = func()[2:4].

Se você estiver usando Python 3, você pode usar a estrela antes de uma variável (no lado esquerdo de uma atribuição) para tê-lo ser uma lista de descompactação.

# Example 1: a is 1 and b is [2, 3]

a, *b = [1, 2, 3]

# Example 2: a is 1, b is [2, 3], and c is 4

a, *b, c = [1, 2, 3, 4]

# Example 3: b is [1, 2] and c is 3

*b, c = [1, 2, 3]       

# Example 4: a is 1 and b is []

a, *b = [1]

Lembre-se, quando você retornar mais de um item, você está realmente retornando uma tupla. Então, você pode fazer coisas como esta:

def func():
    return 1, 2

print func()[0] # prints 1
print func()[1] # prints 2

A prática comum é usar o _ variável dummy (único sublinhado), como muitos têm indicado aqui antes.

No entanto, para evitar colisões com outros usos do que o nome da variável (ver esta resposta ) que poderia ser uma melhor prática para uso __ (duplo sublinhado) em vez como uma variável descartável, tal como apontado por ncoghlan . Por exemplo:.

x, __ = func()

Três escolhas simples.

Óbvio

x, _ = func()

x, junk = func()

Hideous

x = func()[0]

E há maneiras de fazer isso com um decorador.

def val0( aFunc ):
    def pick0( *args, **kw ):
        return aFunc(*args,**kw)[0]
    return pick0

func0= val0(func)

Esta parece ser a melhor escolha para mim:

val1, val2, ignored1, ignored2 = some_function()

Não é críptico ou feio (como o func () [índice] método), e afirma claramente a sua finalidade.

Esta não é uma resposta direta à pergunta. Pelo contrário, responde a esta pergunta: "? Como faço para escolher uma saída de função específica de muitas opções possíveis"

Se você é capaz de escrever a função (ou seja, não é em uma biblioteca não é possível modificar), em seguida, adicione um argumento de entrada que indica que você quer fora da função. Torná-lo um argumento nomeado com um valor padrão para que no "caso comum" você não tem sequer a especificá-lo.

    def fancy_function( arg1, arg2, return_type=1 ):
        ret_val = None
        if( 1 == return_type ):
            ret_val = arg1 + arg2
        elif( 2 == return_type ):
            ret_val = [ arg1, arg2, arg1 * arg2 ]
        else:
            ret_val = ( arg1, arg2, arg1 + arg2, arg1 * arg2 ) 
        return( ret_val )

Este método dá a função de "alerta avançado" sobre a saída desejada. Por conseguinte, pode ignorar o processamento desnecessário e só fazer o trabalho necessário para obter a sua saída desejada. Também porque Python faz tipagem dinâmica, o tipo de retorno pode mudar. Observe como o exemplo retorna um escalar, uma lista ou uma tupla ... o que quer que você gosta!

A melhor solução, provavelmente, é nomear as coisas em vez de retornar tuplas sem sentido. A menos que haja alguma lógica por trás da ordem dos itens devolvidos.

def func():
    return {'lat':1, 'lng':2}

latitude = func()['lat']
print(latitude)

Você poderia até usar namedtuple se você quiser adicionar informações extras sobre o que você está retornando:

from collections import namedtuple 
Coordinates = namedtuple('Coordinates', ['lat', 'lng'])

def func():
    return Coordinates(lat=1, lng=2)

latitude = func().lat
print(latitude)

Se as coisas que retornam são muitas vezes juntos, então ele pode ser uma boa idéia para até mesmo definir uma classe para ele.

Se esta é uma função que você usa todo o tempo, mas sempre descarte o segundo argumento, eu diria que é menos confuso para criar um alias para a função sem o segundo valor de retorno usando lambda.

def func():
    return 1, 2

func_ = lambda: func()[0] 

func_()  # Prints 1 

Quando você tem muitos saída de uma função e você não quiser chamá-lo várias vezes, eu acho que a maneira mais clara para selecionar os resultados seriam:

results = fct()
a,b = [results[i] for i in list_of_index]

Como um exemplo mínimo de trabalho, demonstrando também que a função é chamada apenas uma vez:

def fct(a):
    b=a*2
    c=a+2
    d=a+b
    e=b*2
    f=a*a
    print("fct called")
    return[a,b,c,d,e,f]

results=fct(3)
> fct called

x,y = [results[i] for i in [1,4]]

E os valores são como esperado:

results
> [3,6,5,9,12,9]
x
> 6
y
> 12

Para maior comodidade, os índices de lista do Python também pode ser usado:

x,y = [results[i] for i in [0,-2]]

Retorna: a = 3 e b = 12

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top