在Python中,可以让函数返回多个值。这里有一个人为的例子:
def divide(x, y):
quotient = x/y
remainder = x % y
return quotient, remainder
(q, r) = divide(22, 7)
这似乎很有用,但看起来它也可能被滥用("好吧..函数x已经计算出作为中间值所需要的东西。"让x返回该值)。
你应该什么时候画线和定义一个不同的方法?
绝对(例如您提供的示例)。tuples是python中的头等公民
有一个内建函数divmod()可以做到这一点。
q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x
还有其他例子:zip、enumerate、dict.items。
for i, e in enumerate([1, 3, 3]):
print"index=%d, element=%s" % (i, e)
# reverse keys and values in a dictionary
d = dict((v, k) for k, v in adict.items()) # or
d = dict(zip(adict.values(), adict.keys()))
顺便说一句,大多数时候不需要括号。从python库引用参考:
Tuples may be constructed in a number of ways:
Using a pair of parentheses to denote the empty tuple: ()
Using a trailing comma for a singleton tuple: a, or (a,)
Separating items with commas: a, b, c or (a, b, c)
Using the tuple() built-in: tuple() or tuple(iterable)
功能应为单一目的服务
因此,它们应该返回单个对象。在您的例子中,这个对象是一个元组。将元组视为特殊的复合数据结构。有些语言几乎每个函数都返回多个值(lisp中的列表)。
有时返回(x, y)而不是Point(x, y)就足够了。命名元组
在Python2.6中引入命名元组后,在许多情况下,最好返回命名元组,而不是纯元组。
>>> import collections
>>> Point = collections.namedtuple('Point', 'x y')
>>> x, y = Point(0, 1)
>>> p = Point(x, y)
>>> x, y, p
(0, 1, Point(x=0, y=1))
>>> p.x, p.y, p[0], p[1]
(0, 1, 0, 1)
>>> for i in p:
... print(i)
...
0
1
使用这样的元组的能力是非常方便的。我真的很怀念爪哇的那种能力。
非常感谢您提到命名的tuples。我一直在找这样的东西。
对于有限的返回值,dict()可能更简单/更快(特别是如果函数随后用于RESTAPI和JSON)。在我的系统上,def test_nt():point=namedtuple('point',['x','y'])p=point(10.5,11.5)json.dumps(p._asdict())取819μs/循环,def test_dict():d='x':10.5,'y':11.5 json.dumps(d)取15.9μs/循环….所以>快50倍
@孔德:是的,Point(10.5, 11.5)比{'x': 10.5, 'y':11.5}慢6倍。绝对时间是635 ns +- 26 ns对105 ns +- 4 ns。这两者都不太可能成为应用程序中的瓶颈——除非探查器另有说明,否则不要进行优化。不要在函数级别创建类,除非您知道为什么需要它。如果您的API需要dict,而不是使用dict,那么这与性能无关。
首先,注意python允许以下内容(不需要括号):
q, r = divide(22, 7)
关于你的问题,没有硬性和快速的规则。对于简单的(通常是人为的)例子,似乎给定函数总是可能有一个单一的用途,从而产生一个单一的值。但是,在将Python用于实际应用程序时,您很快就会遇到许多情况,其中需要返回多个值,从而导致代码更干净。
所以,我想说,做任何有意义的事情,不要试图遵守一个人为的约定。python支持多个返回值,因此在适当的时候使用它。
我想看看这样的案子,你能给我看看吗?
逗号创建元组,因此表达式:q, r是一个元组。
Vinko的一个例子是标准库中的tempfile.mkstemp(),它返回一个包含文件句柄和绝对路径的元组。肯尼迪,是的,你说得对。
但这只是一个目的…您可以有单用途和多个返回值
如果其他语言可以有多个返回类型,我就不会陷入引用和"out"参数的困境。
返回多个值是Python中最大的功能之一!
您给出的示例实际上是一个名为divmod的python内置函数。所以有人,在某个时间点上,认为这是一个足以包含在核心功能的Python。
对我来说,如果代码更干净,那就是Python。比较这两个代码块:
seconds = 1234
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
seconds = 1234
minutes = seconds / 60
seconds = seconds % 60
hours = minutes / 60
minutes = minutes % 60
是的,返回多重价值(i.e.,a tuple)是定义的Python。由于其他人已经指明,在Python标准图书馆以及在适当的Python项目中都有许多例子。另外两个评论:
回报多重价值有时非常有用。举例来说,采用一种可选择地处理某一事件(在这样做时回报某些价值)的方法,同时又回报成功或失败。这可能是一个责任模式的链条。在其他情况下,你想要复制多个,封闭链接数据的一部分----例如在给出的例子中。在这一设定中,回归多值是返回一个匿名类的单个实例,其中有多个成员变量。
Python's handling of method determinates necessitates the ability to directly return multiple values.例如,在C++中,方法参数可以通过引用来传输,因此,可以将输出值分配给他们,再加上形式回报值。In Python,are passed"by reference"(but in the sense of Java,not C+).你不能为方法论据分配新的价值,它反射出方法范围。For example:
// C++
void test(int& arg)
{
arg = 1;
}
int foo = 0;
test(foo); // foo is now 1!
比较:
ZZU1
"一种可选地处理事件并返回成功或失败的方法"——这就是异常的原因。
人们普遍认为,例外只适用于"例外"的情况,而不仅仅是成功或失败。谷歌"错误代码与例外"进行了一些讨论。
OT:RSRE's algol68 has the curious"/EG
INT quotient:=355, remainder;
remainder := (quotient /:= 113);
给出一个商数,3,16。
注:Typically the value of(X/:=Y)"is discarded as quote"X"is assigned by reference,but in RSRE's case the returned value is the remainder.
C.F.Integer算法-算法68
返回元组很酷。还要注意新的名称在python 2.6中添加了这个选项,这可能会使您更喜欢它:http://docs.python.org/dev/library/collections.html collections.namedtuple
当然是Python。事实上,您可以从一个函数返回多个值,这个函数是您在C语言中使用的样板文件,在C语言中,您需要为在某个地方返回的每个类型组合定义一个结构。
但是,如果您达到了从一个函数返回疯狂值(比如10个值)的程度,那么您应该认真考虑将它们捆绑在一个类中,因为在这一点上,它会变得很难处理。
我是新来的Python,但水管技术看起来像是我的Python。但是,我有另一个想法,也许可以提高可行性。使用一个字典允许存取到不同值的名称比位置。For example:
def divide(x, y):
return {'quotient': x/y, 'remainder':x%y }
answer = divide(22, 7)
print answer['quotient']
print answer['remainder']
不要这样做。你不能在一行中指定结果,它非常笨拙。(除非您想存储结果,在这种情况下最好将其放入一个方法中。)如果您对dict的意图是自我记录返回值,那么a)给fn一个合理的解释名称(如"divmod"),b)将解释的其余部分放入docstring(即放置它们的pythonic位置);如果docstring请求比两行长,这意味着功能在主题上超载,可能是个坏主意。
对于诸如divmod这样的简单函数,可以使用元组返回多个值。如果它使代码可读,那就是Python。
如果返回值开始变得混乱,请检查函数是否做得太多,如果做得太多,则将其拆分。如果一个大元组被当作一个对象来使用,就把它变成一个对象。另外,考虑使用命名的元组,它将是Python2.6中标准库的一部分。