Python解包中的默认值
Posted
技术标签:
【中文标题】Python解包中的默认值【英文标题】:Default value in Python unpacking 【发布时间】:2015-11-04 14:57:20 【问题描述】:如果要解包的值的数量与变量列表相比太少,有没有办法设置默认值?
例如:
a, b, c = read_json(request)
如果read_json
返回一个包含三个或更多变量的数组,则此方法有效。如果它只返回两个,我在分配c
时会遇到异常。那么,如果无法正确解包,有没有办法将c
设置为默认值?比如:
a, b, (c=2) = read_json(request)
这与定义带有默认参数的函数时所做的类似。
谢谢!
【问题讨论】:
read_json()
是你自己的函数吗?如果是这样,你为什么不能确保它总是返回 3 个值?
不,没有;你需要确保你得到三个值,或者在赋值的右侧填充和切片。
您可以使用 *
解包,例如a, b, *c = read_json(request)
,其中仅解压缩两个值会导致 c
为空 list
,但如果您确实需要特定值,最好让函数 return
更严格一些。
@TigerhawkT3 且仅在 Python 3.x 中
@jonrsharpe - 当然在 Python 3 中……每个人都使用 Python 3……对吗?请? :P
【参考方案1】:
您可以使用chain function from itertools,它是 Python 标准库的一部分。如果第一个列表中没有值,它将用作默认填充符。在我的示例中,'defaults' 列表变量可以为您解压缩的每个变量具有多个不同的值(在示例中,我将所有三个值的默认值都设为 0)。
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() 而不是 *_ 来限制项目的数量? 不幸的是,这只有在所有默认值都相同的情况下才有效,因为链从defaults
的开头开始补充【参考方案2】:
您可以尝试*
进行一些后处理解包:
a, b, *c = read_json(request)
c = c[0] if c else 2
这将照常分配a
和b
。如果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
【讨论】:
【参考方案3】:在回答这个问题时,你不能这样做。
此外,我建议不要从函数返回不同数量的参数 - 这只会导致进一步的问题(this question case in point)。每次调用该函数时,您都需要测试是否返回了 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']
【讨论】:
以上是关于Python解包中的默认值的主要内容,如果未能解决你的问题,请参考以下文章