python:用以前的非零值替换零
我想用Python中的数字列表,用前面的非零值替换所有的零,例如python:用以前的非零值替换零,python,Python,我想用Python中的数字列表,用前面的非零值替换所有的零,例如[1,0,0,2,0]应该给出[1,1,1,2,2]。我知道列表中的第一个条目是非零的,所以初始化应该不会有问题。我可以在一个循环中完成它,但是有没有一种更像蟒蛇的方式呢 澄清一下:这应该适用于任何数字列表,例如[100.7,0,-2.34]应该变成[100.7,100.7,-2.34]这只不过是一个简单易读的循环。但是 >>> my_list = [1, 0, 0, 2, 0] >>> def
[1,0,0,2,0]
应该给出[1,1,1,2,2]
。我知道列表中的第一个条目是非零的,所以初始化应该不会有问题。我可以在一个循环中完成它,但是有没有一种更像蟒蛇的方式呢
澄清一下:这应该适用于任何数字列表,例如
[100.7,0,-2.34]
应该变成[100.7,100.7,-2.34]
这只不过是一个简单易读的循环。但是
>>> my_list = [1, 0, 0, 2, 0]
>>> def set_sentinel(x):
... global sentinel
... sentinel = x
... return False
...
>>> [set_sentinel(elem) or elem if elem else sentinel for elem in my_list]
[1, 1, 1, 2, 2]
您可以利用可变默认参数来避免全局或静态变量来存储最后一个none-zero元素:
def val(x,z=[0]):
if x:
z[0] = x
return z[0]
[val(x) for x in a]
将产生预期的
[1,1,1,2,2]
如果您明确希望避免的循环,这里有一个单行程序。但这并不像循环那样有效
>>> l = [1, 0, 0, 2, 0]
>>> [l[i] if l[i] else filter(lambda x: x > 0, l[:i])[-1] for i in range(len(l))]
[1, 1, 1, 2, 2]
对于每个为零的元素,您将查找该元素之前的所有非零元素,并获取最后一个。冒着听起来陈腐的风险。。不,使用循环。我认为这是表达你想要的最清晰的方式
for i in range(1, len(a)):
if a[i] == 0:
a[i] = a[i-1]
我见过许多以“蟒蛇”的名义犯下的暴行。根据最能表达你意图的方式仔细选择。不要试图盲目地优化最少的代码行或最聪明的实现。这可以在一个很短的循环中完成:
a = [1, 0, 0, 2, 0]
b = []
for i in a:
b.append(i if i else b[-1])
print b
# [1, 1, 1, 2, 2]
仅当存在以前的非零值时有效(即,如果a以0开头,则失败)
由于无法从内部引用列表理解,因此不能将其作为列表压缩,在3.3中,有一行使用了累加:
>>> from itertools import accumulate
>>> seq = [1, 0, 0, 2, 0]
>>> list(accumulate(seq, lambda x,y: y if y else x))
[1, 1, 1, 2, 2]
>>> seq = [100.7, 0, -2.34]
>>> list(accumulate(seq, lambda x,y: y if y else x))
[100.7, 100.7, -2.34]
(我想也可以使用或
,但我发现三元组更容易阅读。)密切投票人:想解释一下为什么你认为它缺少回答问题的信息吗?对我来说,这似乎非常清楚。for
循环中没有什么不和谐的。出于好奇,你如何使用for循环来解决它?你只需要跟踪最后一个非零元素。实际上,不需要跟踪,如果a[i]==0:a[i]=a[i-1]
,那么在这种情况下,最后一个元素就是应该设置为的元素(当然,假设您可以操纵原始列表…)这就是为什么我说不推荐使用它的原因。(我认为这是我第一次真正有意使用可变默认参数功能…)哇。我认为这比使用全局的解决方案更糟糕。我不推荐它,因为它依赖于语言的语义,而这些语义通常只有在被一些真正令人困惑的错误咬过之后才能理解。enumerate
生成一个index,element
的元组。在这里,我不想直接使用元素,所以它不是Pythonic引入了一个您不打算使用的变量。您可以使用[i-1]来取消x的使用。@njzk2经过编辑以反映您的建议。这应该是答案。