简体   繁体   English

Python 解包中的默认值

[英]Default value in Python unpacking

Is there a way to have a default value if the number of values to unpack is too little compared to the variable list?如果与变量列表相比要解包的值的数量太少,是否有一种方法可以获得默认值?

For example:例如:

a, b, c = read_json(request)

This works if read_json returns an array of three or more variable.如果read_json返回包含三个或更多变量的数组,则此方法有效。 If it only returns two, I get an exception while assigning c .如果它只返回两个,我在分配c时会遇到异常。 So, is there a way to set c to a default value if it can't be unpacked properly?那么,如果c无法正确解包,有没有办法将其设置为默认值呢? Something like:就像是:

a, b, (c=2) = read_json(request)

Which is similar to what you do when defining a function with default arguments.这类似于您在定义默认值为 arguments 的 function 时所做的事情。

Thank you!谢谢!

You could try * unpacking with some post-processing:您可以尝试*使用一些后处理解包:

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

This will assign a and b as normal.这将正常分配ab If c is assigned something, it will be a list with one element.如果c被分配了一些东西,它将是一个包含一个元素的list If only two values were unpacked, it will be an empty list .如果只解压了两个值,它将是一个空list The second statement assigns to c its first element if there is one, or the default value of 2 otherwise.如果有一个,则第二个语句将其第一个元素分配给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

You can use chain function from itertools , which is part of the Python standard library.您可以使用itertools 中的链函数,它是 Python 标准库的一部分。 It serve as default filler in case if there are no values in the first list.如果第一个列表中没有值,它会用作默认填充符。 'defaults' list variable in my example can have number of different values for each variable that you unpack (in an example I have default value for all three values as 0).在我的示例中,'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)

Outputs:输出:

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

In answer to the question no you can't do that.在回答这个问题时,你不能这样做。

Furthermore I would recommend against returning different numbers of arguments from functions - this will only cause compilcations further issues down the line (this question case in point).此外,我建议不要从函数返回不同数量的参数 - 这只会导致进一步的问题(this question case in point)。 Everytime you call that function you will need to test if there were 2 or 3 values returned.每次调用该函数时,您都需要测试是否返回了 2 个或 3 个值。 (Unpacking could be useful here, but you will still need to check those returned variables). (解包在这里可能很有用,但您仍然需要检查那些返回的变量)。 eg:例如:

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

It would make more sense, assuming read_json is your function, if the function can return a dict with the default values set:假设 read_json 是您的函数,如果该函数可以返回具有默认值集的 dict ,这将更有意义:

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

    return ret

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

Is there a way to have a default value if the number of values to unpack is too little compared to the variable list?如果要解压缩的值的数量与变量列表相比太少,是否可以使用默认值?

For example:例如:

a, b, c = read_json(request)

This works if read_json returns an array of three or more variable.如果read_json返回三个或三个以上变量的数组,则此方法有效。 If it only returns two, I get an exception while assigning c .如果它仅返回两个,则在分配c出现异常。 So, is there a way to set c to a default value if it can't be unpacked properly?因此,如果无法正确解压缩,是否可以将c设置为默认值? Something like:就像是:

a, b, (c=2) = read_json(request)

Which is similar to what you do when defining a function with default arguments.这与使用默认参数定义函数时的操作类似。

Thank you!谢谢!

If you would like a one-liner solution, the following trick using default parameters in lambda functions will work, but it is somewhat confusing and hard to read:如果您想要一个单行解决方案,可以使用以下在 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)

Output: Output:

1 2 3
1 2 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM