忽略python多重返回值

Posted

技术标签:

【中文标题】忽略python多重返回值【英文标题】:Ignore python multiple return value 【发布时间】:2010-09-30 17:15:24 【问题描述】:

假设我有一个 Python 函数,它在一个元组中返回多个值:

def func():
    return 1, 2

有没有一种很好的方法来忽略其中一个结果,而不仅仅是分配给一个临时变量?假设我只对第一个值感兴趣,有没有比这更好的方法:

x, temp = func()

【问题讨论】:

我也很好奇这来自 Matlab 的 Ignore Function Outputs 的类似概念,他们使用 ~ 作为忽略特定返回变量的语法 您选择了错误的答案作为解决方案 【参考方案1】:

您可以使用x = func()[0] 返回第一个值,x = func()[1] 返回第二个值,依此类推。

如果您想一次获取多个值,请使用 x, y = func()[2:4] 之类的内容。

【讨论】:

这应该是公认的答案。如果您只想要一些的返回值,也可以使用func()[2:4]之类的东西。 它不会多次调用该函数:>>> def test(): ... print "here" ... return 1,2,3 ... >>> a, b = test()[:2] 这里 [编辑:抱歉代码没有通过,显然你在 cmets 中只有一行。对于那些不熟悉的人来说 >>> 和 ... 是 python shell 中新行的开始] @TylerLong:我认为_, _, _, _, _, _, _, _, _, _, _, _, _, a, _, _, _, _, _, _, _, _, _, _, _, b, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, c, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, d, _, _, _, _, _, _, _, _, e, _ = func() 不如多次调用该函数清晰,但这只是我的看法。如果您的函数返回这么多项目,我认为使用 numpy 会更好:a, b, c, d, e = func()[[13, 25, 58, 89, 98]] @endolith 我觉得这样更好,不需要numpy也不需要多次调用func():result = func()a = result[13]b = result[25]... 当你想忽略中间的一个或几个值时,这种风格并不好,例如x, __, y = func()【参考方案2】:

一个常见的约定是使用“_”作为要忽略的元组元素的变量名。例如:

def f():
    return 1, 2, 3

_, _, x = f()

【讨论】:

-1:当您将 gettext 功能添加到其他人的代码(定义了一个名为 '_' 的函数)中时,这个“约定”很糟糕,所以应该禁止它 好点子——尽管 gettext 坚持安装一个名为“”的函数是否是个好主意还有待商榷。个人觉得有点丑。无论如何,使用“”作为一次性变量是很普遍的。 -1: _ 在 IPython 中表示“最后一个输出”。我永远不会给它分配任何东西。 好的,我没有注意到“我” - 感谢您的参考。恕我直言,您不能仅仅因为一个 Python 应用程序为它定义了自己的神奇用途,就期望其他人不使用变量。 某些 IDE(例如 PyDev)会对此发出警告,因为您有未使用的变量。【参考方案3】:

如果您使用的是 Python 3,您可以在变量前使用星号(在赋值的左侧)使其成为解包时的列表。

# 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]

【讨论】:

您还可以使用a, *_ = f() 忽略a 之后的任意数量的返回值。【参考方案4】:

通常的做法是使用虚拟变量_(单下划线),正如许多人之前在此处指出的那样。

但是,为避免与该变量名的其他用途发生冲突(请参阅this 响应),最好使用__(双下划线)作为一次性变量,正如ncoghlan 所指出的那样。例如:

x, __ = func()

【讨论】:

一点也不坏。但随后 '_ _' 将在命名空间中声明一个变量。然而,除非像上面那样在赋值语句的左侧特别使用,否则'_'不会声明(例如:a, _, _ = 1,8,9)。在那之前,它会存储执行的最后一条语句的结果,如果要捕获该结果,通常会使用变量来存储该值。这就是为什么,'_'是建议的变量名来捕获垃圾值。 ' _ ' 值在另一个语句执行后很快被覆盖。在 '_ _' 的情况下,值将保留在那里,直到 GC 将其清除。【参考方案5】:

请记住,当您返回多个项目时,您实际上是在返回一个元组。所以你可以这样做:

def func():
    return 1, 2

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

【讨论】:

对语法很有用。这样做的一个问题是它需要多次调用该函数。对于这样一个微不足道的功能,这没什么大不了的。但是,在更复杂的功能中,这可能是不可取的。很高兴知道有很多方法....【参考方案6】:

三个简单的选择。

很明显

x, _ = func()

x, junk = func()

丑陋的

x = func()[0]

还有一些方法可以用装饰器来做到这一点。

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

func0= val0(func)

【讨论】:

我真的更喜欢 _ 变量。很明显,您忽略了一个值 你的例子是倒退的。 x, _ = func() 很丑陋,x = func()[0] 很明显。分配给变量然后不使用它?该函数正在返回一个元组;像元组一样索引它。 在模式匹配语言中,Python 从中派生了这种模式,“显而易见”的方法确实是显而易见的,并不可怕,而且是规范的。虽然,在此类语言中,通配符是受支持的语言功能,而在 Python 中,它是一个真正的变量并被绑定,这有点令人不快。 对于列表处理语言,Python 派生自;),列表访问器如a[0]a[:](列表副本)、a[::2](每两个元素)和@987654331 @(旋转列表),确实,也很明显和规范。【参考方案7】:

最好的解决方案可能是命名事物而不是返回无意义的元组(除非返回项目的顺序背后有一些逻辑)。例如,您可以使用字典:

def func():
    return 'lat': 1, 'lng': 2
    
latitude = func()['lat']

如果您想添加有关您返回的内容的额外信息,您甚至可以使用namedtuple(它不仅仅是一个字典,它是一对坐标):

from collections import namedtuple 

Coordinates = namedtuple('Coordinates', ['lat', 'lng'])

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

latitude = func().lat

如果您的字典/元组中的对象紧密联系在一起,那么为它定义一个类可能是个好主意。这样,您还可以定义更复杂的操作。接下来的一个自然问题是:When should I be using classes in Python?

python 的最新版本(≥ 3.7)有dataclasses,您可以使用它来用很少的代码行定义类:

from dataclasses import dataclass

@dataclass
class Coordinates:
    lat: float = 0
    lng: float = 0

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

latitude = func().lat

数据类相对于namedtuple 的主要优势在于它更易于扩展,但有other differences。请注意,默认情况下,数据类是可变的,但您可以使用 @dataclass(frozen=True) 而不是 @dataclass 来强制它们不可变。

Here is a video 这可能会帮助您为您的用例选择正确的数据类。

【讨论】:

这是唯一能找到隐藏在这个问题中的问题核心的答案。如果您试图选择一个函数的元组输出之一,它们可能不应该在一个元组中。元组用于以有序方式“一起”的事物。在 OP 的情况下,它们(可能)是“质量不同”的输出,应该以某种方式命名。当没有自然顺序时,让读者理解第一个和第二个输出指的是什么,这是一个麻烦的秘诀。【参考方案8】:

如果这是一个你一直使用但总是丢弃第二个参数的函数,我认为使用lambda 为没有第二个返回值的函数创建别名不会那么麻烦。

def func():
    return 1, 2

func_ = lambda: func()[0] 

func_()  # Prints 1 

【讨论】:

【参考方案9】:

这对我来说似乎是最好的选择:

val1, val2, ignored1, ignored2 = some_function()

它并不神秘或丑陋(如 func()[index] 方法),并且清楚地说明了您的目的。

【讨论】:

【参考方案10】:

这不是问题的直接答案。相反,它回答了这个问题:“我如何从许多可能的选项中选择一个特定的函数输出?”。

如果您能够编写函数(即,它不在您无法修改的库中),则添加一个输入参数,表明您希望从函数中得到什么。使其成为具有默认值的命名参数,因此在“常见情况”中您甚至不必指定它。

    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 )

此方法提供有关所需输出的“高级警告”功能。因此,它可以跳过不需要的处理,只做获得所需输出所需的工作。同样因为 Python 进行动态类型,所以返回类型可以改变。请注意该示例如何返回标量、列表或元组......任何你喜欢的!

【讨论】:

【参考方案11】:

当一个函数有很多输出并且不想多次调用它时,我认为选择结果的最清晰方法是:

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

作为一个最小的工作示例,也证明该函数只被调用一次:

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]]

而且值符合预期:

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

为方便起见,也可以使用 Python 列表索引:

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

返回:a = 3 和 b = 12

【讨论】:

以上是关于忽略python多重返回值的主要内容,如果未能解决你的问题,请参考以下文章

解决protobuf忽略空返回值的问题

如何优雅地忽略 MATLAB 函数的某些返回值

忽略 PL/SQL 函数的返回值

TipsPython 针对函数返回值实现列表推导

Python类和对象_嵌入_多实例返回值

Vue数据函数返回值,但vue忽略它们