如果太短,会自动将Python列表扩展到N个元素吗?

时间:2019-12-02 00:11:19

标签: python list

如果列表中的元素少于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

但是必须要有比这更优雅的东西。

7 个答案:

答案 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)

thisthis的启发,基于装饰器的灵活解决方案:

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))