return返回字符串 - python返回多个数组




你如何在Python中返回多个值? (9)

在支持它的语言中返回多个值的规范方式通常很tupling

选项:使用元组

考虑这个微不足道的例子:

def f(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return (y0,y1,y2)

但是,随着返回值的数量增加,这很快就会出现问题。 如果你想返回四个或五个值呢? 当然,你可以继续把它们弄脏,但很容易忘记哪个值是在哪里。 将它们解包到任何你想接收它们的地方也是相当难看的。

选项:使用字典

下一个合乎逻辑的步骤似乎是引入某种“记录符号”。 在Python中,执行此操作的显而易见的方法是通过dict

考虑以下:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

(编辑 - 为了清楚起见,y0,y1和y2只是抽象的标识符,正如指出的那样,在实践中你会使用有意义的标识符)

现在,我们有了一个机制,可以将返回对象的特定成员投影出来。 例如,

result['y0']

选项:使用一个类

但是,还有另一种选择。 我们可以返回一个专门的结构。 我已经在Python的上下文中构建了这个框架,但我相信它也适用于其他语言。 事实上,如果你在C工作,这可能是你唯一的选择。 开始:

class ReturnValue(object):
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return ReturnValue(y0, y1, y2)

在Python中,前两者在管道方面可能非常相似 - 毕竟{ y0, y1, y2 }最终只能作为ReturnValue的内部__dict__中的条目。

Python为小对象提供了一个额外的功能,即__slots__属性。 这个班可以表达为:

class ReturnValue(object):
  __slots__ = ["y0", "y1", "y2"]
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

Python参考手册

__slots__声明采用一系列实例变量,并在每个实例中保留足够的空间以保存每个变量的值。 空间被保存,因为__dict__不是为每个实例创建的。

选项:使用列表

我忽略的另一个建议来自比尔蜥蜴:

def h(x):
  result = [x + 1]
  result.append(x * 3)
  result.append(y0 ** y3)
  return result

尽管这是我最不喜欢的方法。 我想我已经接触到Haskell,但混合类列表的想法一直让我感到不舒服。 在这个特定的例子中,列表是非混合类型,但它可能是可以的。 据我所知,以这种方式使用的列表实际上并没有获得关于元组的任何信息。 Python中的列表和元组之间唯一真正的区别是列表是mutable ,而元组则不是。 我个人倾向于继承函数式编程的约定:使用相同类型的任意数量元素的列表,以及固定数量的预定类型元素的元组。

在长篇序言之后,出现不可避免的问题。 哪种方法(你认为)最好?

我通常会发现自己要去字典路线,因为它涉及的设置工作较少。 然而,从类型的角度来看,您最好走上课程路线,因为这可能会帮助您避免混淆字典所代表的内容。 另一方面,Python社区中有一些人认为隐式接口应该比显式接口更受欢迎 ,此时对象的类型实际上并不相关,因为您基本上依赖于约定,即相同的属性将始终具有相同的含义。

那么,如何在Python中返回多个值?


Python的元组,字典和对象为程序员提供了小数据结构(“事物”)的正式性和便利性之间的平衡权衡。 对我而言,如何表现事物的选择主要取决于我将如何使用该结构。 在C ++中,尽管可以合法地将方法放在struct上,但对于使用方法的对象而言,使用struct来处理纯数据项和class是一种常见惯例; 我的习惯在Python中类似,用dicttuple代替struct

对于坐标集,我将使用一个tuple而不是一个点classdict (并且请注意,您可以使用tuple作为字典关键字,因此dict可以创建稀疏的多维数组)。

如果我要迭代一系列事物,我更喜欢在迭代中解开tuple s:

for score,id,name in scoreAllTheThings():
    if score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(score,id,name)

...因为对象版本更加混乱:

for entry in scoreAllTheThings():
    if entry.score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry.score,entry.id,entry.name)

...更不用说dict

for entry in scoreAllTheThings():
    if entry['score'] > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry['score'],entry['id'],entry['name'])

如果这个东西被广泛使用,并且你发现自己在代码的多个地方对它做类似的非平凡操作,那么通常有必要用适当的方法将它变成一个类对象。

最后,如果我要与非Python系统组件交换数据,我经常会将它们保留为dict因为它最适合JSON序列化。


S.Lott提出的命名容器类的建议+1。

对于python 2.6或更高版本, 命名元组提供了一种轻松创建这些容器类的有用方法,并且结果是“轻量级且不需要比常规元组更多的内存”。


为此目的, 命名元组被添加到2.6中。 另请参阅os.stat以获取类似的内置示例。

>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2

另一种选择是使用发电机:

>>> def f(x):
        y0 = x + 1
        yield y0
        yield x * 3
        yield y0 ** 4


>>> a, b, c = f(5)
>>> a
6
>>> b
15
>>> c
1296

虽然恕我直言元组通常是最好的,除非返回的值是封装在类中的候选者。


对于小型项目,我发现使用元组最容易。 当它太难管理(而不是之前)时,我开始将事物分组为逻辑结构,但是我认为你建议使用的字典和ReturnValue对象是错误的(或者过于简单)。

用键y0,y1,y2等返回一个字典不会比元组提供任何优势。 使用属性.y0 .y1 .y2等返回一个ReturnValue实例不会比元组提供任何优势。 你需要开始命名的东西,如果你想得到任何地方,你可以用元组来做到这一点:

def getImageData(filename):
  [snip]
  return size, (format, version, compression), (width,height)
size, type, dimensions = getImageData(x)

恕我直言,除了元组之外,唯一的好技术就是使用正确的方法和属性返回真实对象,就像从re.match()open(file)


很多答案建议您需要返回某种类型的集合,如字典或列表。 您可以省略额外的语法,只需写出返回值,用逗号分隔。 注意:这在技术上返回一个元组。

def f():
    return True, False
x, y = f()
print(x)
print(y)

得到:

True
False

我投票给字典。

我发现如果我创建一个返回超过2-3个变量的函数,我会把它们放到一本字典中。 否则,我倾向于忘记我返回的顺序和内容。

此外,引入“特殊”结构会使您的代码更难以遵循。 (其他人将不得不搜索代码来找出它是什么)

如果您关心类型查询,请使用描述性字典键,例如'x-values list'。

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

我更喜欢

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

看起来其他一切只是额外的代码来做同样的事情。


>>> def func():
...    return [1,2,3]
...
>>> a,b,c = func()
>>> a
1
>>> b
2
>>> c
3




return-value