Python解包中的默认值

30

如果要解包的值太少与变量列表相比,是否有一种方法可以设置默认值?

例如:

a, b, c = read_json(request)

如果read_json返回一个包含三个或更多变量的数组,那么这将起作用。如果它只返回两个,我在分配c时会得到一个异常。那么,如果不能正确解包c,有没有一种方法可以将其设置为默认值?类似于:


a, b, c = read_json()
if len(c) < 3:
    c = default_value
a, b, (c=2) = read_json(request)

这类似于使用默认参数定义函数时所做的操作。

谢谢!


2
read_json() 是你自己的函数吗?如果是,为什么不能确保它始终返回3个值? - Anand S Kumar
1
不,没有;你需要确保你得到三个返回值,或者在赋值的右侧进行填充和切片。 - jonrsharpe
1
你可以使用 * 解包,例如 a, b, *c = read_json(request),其中仅解包两个值将导致 c 成为一个空的 list,但如果你真的需要特定的值,最好让函数 return 一些更严格的内容。 - TigerhawkT3
1
请用 Python 3.x 编写,仅面向 @TigerhawkT3。 - jonrsharpe
1
@jonrsharpe - 当然是在Python 3中...每个人都使用Python 3...对吧?拜托了? :P - TigerhawkT3
显示剩余2条评论
4个回答

35

你可以尝试用一些后处理进行*解压:

a, b, *c = read_json(request)
c = c[0] if c else 2

这将正常地分配ab。如果c被赋值,它将是一个具有一个元素的list。如果只有两个值被解包,它将是一个空的list。第二个语句将为c分配其第一个元素(如果有),否则将分配默认值2

>>> a, b, *c = 1, 2, 3
>>> c = c[0] if c else 2
>>> a
1
>>> b
2
>>> c
3
>>> a, b, *c = 1, 2
>>> c = c[0] if c else 2
>>> a
1
>>> b
2
>>> c
2

10
您可以使用Python标准库中的itertools.chain函数,它可以作为默认填充值在第一个列表中没有值的情况下使用。在我的示例中,“defaults”列表变量可以具有每个要解包的变量的多种不同值(在示例中,我将所有三个值的默认值设置为0)。请参考itertools文档
from itertools import chain

defaults = [0] * 3
data = []

a, b, c, *_ = chain(data, defaults)
print(a, b, c)

data.append(1)
a, b, c, *_ = chain(data, defaults)
print(a, b, c)

data.append(2)
a, b, c, *_ = chain(data, defaults)
print(a, b, c)

data.append(3)
a, b, c, *_ = chain(data, defaults)
print(a, b, c)

data.append(4)
a, b, c, *_ = chain(data, defaults)
print(a, b, c)

输出:

0 0 0
1 0 0
1 2 0
1 2 3
1 2 3

为什么不彻底限制项目数量,而是使用islice()而不是*_? - Ian Goldby
5
很遗憾,这仅适用于所有默认值都相同的情况,因为链式补充始于“defaults”的开头。 - M. Beining

0
如果您想要一个一行代码的解决方案,下面这个使用 lambda 函数中默认参数的技巧可以实现,但是它有些令人困惑和难以阅读:
a, b, c = (lambda a, b, c=3: (a, b, c))(*(1, 2))
print(a, b, c)
a, b, c = (lambda a, b, c=3: (a, b, c))(*(1, 2, 4))
print(a, b, c)

输出:

1 2 3
1 2 4

0

回答这个问题,不,你不能这样做。

此外,我建议不要从函数返回不同数量的参数 - 这只会在后面引起更多的问题和复杂性(正如这个问题所示)。每次调用该函数时,您都需要测试是否返回了2个或3个值。(解包可能在这里有用,但您仍然需要检查这些返回的变量)。例如:

a, b, *others = read_json(request)
if others:
    c = others[0]

假设read_json是您的函数,如果该函数可以返回一个带有默认值设置的字典,则更有意义:

def read_json(request):
    ret = { 'c': 2 }
    # ... set 'a' and 'b' and 'c' if possible

    return ret

res = read_json(request)
c = res['c']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接