如果列表中的元素少于N
,则Python中将列表自动扩展到N
元素的最佳方法是什么?
也就是说,让我输入以下字符串:s = "hello there"
。如果我这样做:
x, y, z = s.split()
我会得到一个错误,因为s.split()
返回了两个元素的列表,但是我将其分配给3个变量。我要给z
分配None
。
我知道我可以用困难的方式做到这一点:
l = s.split()
while len(l) < 3:
l.append(None)
x, y, z = l
但是必须要有比这更优雅的东西。
答案 0 :(得分:21)
如果您想要单线,请执行以下操作:
s = "hello there"
x, y, z, *_ = s.split() + [None, None, None]
print(x, y, z)
输出
hello there None
请注意,单线不一定更易读也不太优雅。 @Grismar带来的变化是:
x, y, z, *_ = s.split() + [None] * 3
答案 1 :(得分:14)
extend
在列表末尾添加一个可迭代项,因此您可以执行以下操作:
l.extend(None for _ in range(3 - len(l))
或
l.extend([None]*(3-len(l)))
这有点优雅,但速度稍慢,因为它需要首先构造Nones列表。
答案 2 :(得分:7)
padnone
中的itertools
食谱正是用于(https://docs.python.org/3/library/itertools.html#itertools-recipes)的食谱:
x, y, z = itertools.islice(itertools.chain(s.split(), itertools.repeat(None)), 3)
上面还结合了take
,只得到3个元素。
答案 3 :(得分:5)
这是一个使用itertools.zip_longest的有趣解决方案:其行为是使用2019-12-01 22:21:45.910 ERROR 16788 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [1510eee8] 500 Server Error for HTTP GET "/v1/customers/123"
java.lang.NullPointerException: null at com.poc.controller.CustomerController.findById(CustomerController.java:19) ~[classes/:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? HTTP GET "/v1/customers/123" [ExceptionHandlingWebHandler]
Stack trace:
at com.poc.webportal.controller.CustomerController.findById(CustomerController.java:19) ~[classes/:na]
来按较短的顺序填充缺少的元素。
bean
就像您的原始代码一样,如果None
包含三个以上的部分,则会引发错误。如果您想静静地丢弃多余的部分,请改成from itertools import zip_longest
(x, _), (y, _), (z, _) = zip_longest(s.split(), range(3))
。
答案 4 :(得分:3)
另一种方法是使用分区将z分配给空白字符串。
s = "hello there"
x, z, y = s.partition(' ')
这种方法切入正题。这样,它将z分配为空白而不是无。
答案 5 :(得分:3)
from itertools import islice, chain, repeat
def variable_return(max_values, default=None):
def decorator(f):
def wrapper(*args, **kwargs):
return islice(chain(f(*args, **kwargs), repeat(default)), max_values)
return wrapper
return decorator
或毫无意义的精简版本:
variable_return = lambda m, d=None: lambda f: lambda *a, **k: islice(chain(f(*a, **k), repeat(d)), m)
可以这样使用:
@variable_return(3)
def split(s):
return s.split()
x, y, z = split(s) # ('hello', 'there', None)
或类似这样:
x, y, z = variable_return(3)(s.split)() # ('hello', 'there', None)
答案 6 :(得分:3)
您可以将单项列表[None]
添加所需的次数(编辑:类似于this,但不使用extend
):
l += [None]*(3-len(l))