假设我有一个python函数,它在一个元组中返回多个值:
1 2
| def func():
return 1, 2 |
有没有一种好的方法可以忽略其中一个结果,而不仅仅是分配给一个临时变量?如果我只对第一个值感兴趣,有没有比这更好的方法:
- 我也很好奇Matlab关于忽略函数输出的类似概念,它们使用~作为语法来忽略特定的返回变量。
- 您选择了错误的答案作为解决方案
您可以使用x = func()[0]返回第一个值,x = func()[1]返回第二个值,依此类推。
如果您希望一次获得多个值,请使用类似于x, y = func()[2:4]的东西。
- 这应该是公认的答案。如果只需要一些返回值,也可以使用func()[2:4]之类的东西。
- 这很糟糕,因为您必须多次调用func()。这是浪费CPU时间
- 它不会多次调用函数:>>>def test():…打印"这里"…返回1、2、3…>>>A,B=test()[:2]这里[edit:抱歉代码没有通过,一方面您只能在注释中得到一行。对于那些不熟悉的人是python shell中新行的开头]
- +1,但只是因为@endolith的评论。
- @泰勒龙:不,你不需要。如果你一次想要一个以上的值,可以使用像x, y = func()[0:1]这样的值。
- @它是有意义的,但不是一般的解决办法。假设func()返回100个值,我想要第13、25、58、89和98个值,那么我仍然需要多次调用func()。
- @泰勒龙:我认为_, _, _, _, _, _, _, _, _, _, _, _, _, a, _, _, _, _, _, _, _, _, _, _, _, b, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, c, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, d, _, _, _, _, _, _, _, _, e, _ = func()比多次调用函数要不清楚,但这只是我的观点。如果您的函数返回这么多项,我认为最好使用numpy:a, b, c, d, e = func()[[13, 25, 58, 89, 98]]
- @我认为这更好,不需要numpy,也不需要多次调用func():result = func()a = result[13]b = result[25]…
- @泰勒龙:是的,我同意。
- 如何将此语法与in语句一起使用,如何时使用for (_, _, x, _) in something():语句?
- @zitrax:以您描述的方式使用这种语法的唯一真正方法是为something()返回的值引入一个变量,即for spam in something():后跟x = spam[2]。
- @Zitrax别忘了,你可以一直保存返回值并重新使用它:result=something(),然后是result[2]等等。
- @endolith当目标是在交互会话期间抑制来自返回单个值的函数的输出时,这显然不起作用。
- @我不明白
- @很好,但这是另一个问题。这个是关于返回序列的东西。你想要像reload(numpy);这样的东西来抑制ipython的输出:stackoverflow.com/q/23692950/125507
- @endolith如果您是教条主义地反对_,那么是的,您可以使用索引和分号的组合来处理函数的不需要的输出。我在思想上并没有这么倾向,所以我将继续使用优雅的通用解决方案_ = . . .,我从来没有写过一个函数,它只返回100个值,这是我实际需要的一个看似随机的子集。
- @你说的都不是同一件事。这个问题是只分配返回对象的一个子集,而您谈论的是在未分配返回对象时禁止IPython打印返回对象。分号就是你要找的。
- 如果您想忽略其中的一个或几个值,例如x, __, y = func(),这种样式就不好了。
- 如果要复制数据,这两种方法之间有什么区别吗?例如,pre-numpy1.11 gradient可能会返回一个相当大的阵列列表。对于输出列表中的其他数组,复制过程是否被x,y = np.gradient(z)[1,2]绕过?
- 这应该是一个例外的答案。
一种常见的约定是使用"u"作为要忽略的元组元素的变量名。例如:
1 2 3 4
| def f():
return 1, 2, 3
_, _, x = f() |
- 很有趣的概念,但不是很Python。然而,我提交的解决方案也不是。我可以问一下,你在哪里听说过这个公约?我想知道它有多受欢迎。
- 这是我以前听说过的概念,但我记不起来了。但我不知道从哪里听说的。
- 我在各种各样的代码中看到过它。如果您在标准的python库中执行grep-w''..py,您将发现它的一些实例。例如,userdict.py有几个实例。我也在Pygments和Django等软件包中看到过。
- @埃文,我发现这是非常Python,特别是考虑到Python喜欢使用下划线。(int."UuMul"、"Iter"、"Builtins"等)
- 它在Python社区中绝对是标准的,我已经做了这么久了,我不记得为什么我开始做它。我很惊讶在第8次政治公众人物会议上没有找到它。
- -1:当您将getText功能添加到其他人的代码(该代码定义了一个名为"uu"的函数)时,这种"约定"很糟糕,因此应该禁止它。
- 很好的一点——尽管gettext坚持安装一个名为"的函数是否是一个好主意还存在争议。就我个人而言,我觉得有点难看。不管怎样,"作为一次性变量的使用很普遍。
- 这一惯例在哈斯克尔也很普遍。有人知道它的起源吗?
- 这很整洁。在我看来,它来自Perl世界。
- 据我所知,源代码是ML。这一点在功能语言中得到了同样的支持,特别是从ML派生/启发的语言,如ocaml、f_、nemerle等。
- -1:u表示ipython中的"最后输出"。我永远不会给它分配什么。
- @内石:需要引证
- @draemon:ipython.scipy.org/doc/manual/html/interactive/…
- 好吧,我没注意到"I"-谢谢你的参考。imho您不能指望其他人不使用变量,因为一个python应用程序定义了它自己的神奇用法。
- 一些IDE(如pydev)会对此发出警告,因为您有未使用的变量。
- @德雷蒙:到目前为止,有两个下划线有其他用途的例子。它不是一次性变量,不应被视为一个变量。函数输出一个元组;像元组一样使用它。
- @这就是重点。python已经分配给_。显式分配给_相当于不分配任何内容,这是目标。(即,通常情况下,_和一个新变量都被分配给——这就省去了新变量。)
- @当然,任何与非python软件不一致的python约定都应该被禁止。见鬼,当我们在这的时候,让我们禁止Python。也许写《江户记》的人可以推荐别的东西。
- @nosklo stackoverflow.com/q/5893163/1394393
- 无论哪个特定的模块想要使用_,当名称可以被其他模块使用时,为什么要使用任何名称并完全放弃它?例如,为什么不直接使用x, print = func()?func()[0]显然要好得多,它真正丢弃了元组中不需要的部分,并且不会污染名称空间。
如果您使用的是python 3,那么可以使用变量前面的星号(在赋值的左侧)将其作为解包中的列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # 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] |
- 是否有针对python2的解决方案?
- 这也适用于元组,以防有人好奇。
通常的做法是使用虚拟变量_(单下划线),正如前面许多人所指出的那样。
但是,为了避免与该变量名的其他用法发生冲突(请参阅此响应),最好使用__(双下划线)代替ncoghlan所指出的一次性变量。例如。:
记住,当您返回多个项时,实际上是返回一个元组。所以你可以这样做:
1 2 3 4 5
| def func():
return 1, 2
print func()[0] # prints 1
print func()[1] # prints 2 |
三个简单的选择。
明显的
1 2 3
| x, _ = func()
x, junk = func() |
丑陋的
有很多方法可以用一个装饰师来做这个。
1 2 3 4 5 6
| 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[:](list copy)、a[::2](每两个元素一个)和a[i:] + a[:i](rotate a list)等列表访问器确实也是明显且规范的。
这不是问题的直接答案。相反,它回答了这个问题:"如何从许多可能的选项中选择特定的函数输出?".
如果您能够编写函数(即,它不在您无法修改的库中),则添加一个输入参数,指示您希望从函数中得到什么。将其设置为具有默认值的命名参数,这样在"常见情况"中甚至不必指定它。
1 2 3 4 5 6 7 8 9
| 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执行动态类型,所以返回类型可以更改。注意示例如何返回标量、列表或元组…不管你喜欢什么!
这似乎是我的最佳选择:
1
| val1, val2, ignored1, ignored2 = some_function() |
它不是神秘的或丑陋的(像func()[index]方法),并且清楚地说明了您的目的。
最好的解决方案可能是命名事物,而不是返回无意义的元组。除非在返回项的顺序后面有一些逻辑。
1 2 3 4 5
| def func():
return {'lat':1, 'lng':2}
latitude = func()['lat']
print(latitude) |
如果要添加有关返回内容的额外信息,甚至可以使用name-duple:
1 2 3 4 5 6 7 8
| from collections import namedtuple
Coordinates = namedtuple('Coordinates', ['lat', 'lng'])
def func():
return Coordinates(lat=1, lng=2)
latitude = func().lat
print(latitude) |
如果您返回的内容经常在一起,那么为它定义一个类可能是一个好主意。
当一个函数有许多输出,并且不想多次调用它时,我认为选择结果的最清晰方法是:
1 2
| results = fct()
a,b = [results[i] for i in list_of_index] |
作为最基本的工作示例,还演示了只调用一次函数:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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]] |
值如预期:
1 2 3 4 5 6
| results
> [3,6,5,9,12,9]
x
> 6
y
> 12 |
为了方便起见,还可以使用python列表索引:
1
| x,y = [results[i] for i in [0,-2]] |
返回:a=3,b=12
如果这是一个您一直在使用但总是放弃第二个参数的函数,那么我认为使用lambda为没有第二个返回值的函数创建别名就不那么麻烦了。
1 2 3 4 5 6
| def func():
return 1, 2
func_ = lambda: func()[0]
func_() # Prints 1 |