在列表中将None替换为最左边的非none值

时间:2015-07-06 21:42:10

标签: python

鉴于

a = [None,1,2,3,None,4,None,None]

我想要

a = [None,1,2,3,3,4,4,4]

目前我粗暴地强迫它:

def replaceNoneWithLeftmost(val):
    last = None
    ret = []
    for x in val:
        if x is not None:
            ret.append(x)
            last = x
        else:
           ret.append(last)
    return ret

最后,我想去

a = [1,1,2,3,3,4,4,4]

从右到左运行。目前我有

def replaceNoneWithRightmost(val):
    return replaceNoneWithLeftmost(val[::-1])[::-1]

我并不挑剔现场或创建一个新的清单,但现在这闻到了我的气味。我看不到存储临时'last'值的方法并使用map / lambda,而且没有别的想法。

6 个答案:

答案 0 :(得分:4)

IIUC,您可以使用itertools.accumulate生成前向填充:

>>> from itertools import accumulate
>>> a = [None,1,2,3,None,4,None,None]
>>> list(accumulate(a, lambda x,y: y if y is not None else x))
[None, 1, 2, 3, 3, 4, 4, 4]

答案 1 :(得分:2)

a = [None,1,2,3,None,4,None,None]

start = next(ele for ele in a if ele is not None)
for ind, ele in enumerate(a):
    if ele is None:
        a[ind] = start
    else:
        start = ele
print(a)
[1, 1, 2, 3, 3, 4, 4, 4]

如果第一个元素为None:

,您还需要将start设置为值
if a[0] is None:
   start = next(ele for ele in a if ele is not None)
for ind, ele in enumerate(a):
    if ele is None:
        a[ind] = start
    else:
        start = ele
print(a)

答案 2 :(得分:0)

这里有一些代码可以执行您想要的操作,如果您不想要它,那么只需将其传递给list(my_list)而不是my_list

def replaceNoneWithLeftmost(val):
    for i in range(len(val)):
        if val[i] is None:
            for j in range(i-1, -1, -1):
                if val[j] is not None:
                    val[i] = val[j]
                    break
    for i in range(len(val)):
        if val[i] is None:
            for j in range(i+1, len(val)):
                if val[j] is not None:
                    val[i] = val[j]
                    break
    return val

此外,如果使用python2,请使用xrange代替range

答案 3 :(得分:0)

a = [None,1,2,3,None,4,None,None]

first = True
for i in range(len(a)):
    if first:
        if a[i] != None:
            a[:i] = [a[i] for _ in range(i)]
            first = False
    if a[i] == None:
        a[i] = a[i-1]

print a

<强> OUT:

[1, 1, 2, 3, 3, 4, 4, 4]

答案 4 :(得分:0)

也可以通过以下方法完成 一个函数,用于查找给定列表中的第一个非None元素 第二个将向前传播之前的非None元素。

纯python ...

l = [None , None , None ,None ,10, 1, 2, 3, None, 4, None, None]

def get_first_non_empty(lst):
    empty = True
    for i in lst:
        if i is not None:
            while empty:
                empty = False
            break
    return i

def get_last_non_empty(lst):
    new_lst = []
    prev = None
    for itm in lst:
        if itm is not None:
            prev = itm
            new_lst.append(itm)
        else:
            if len(new_lst)==0 or prev is None:
                new_lst.append(get_first_non_empty(lst))
            else:
                new_lst.append(prev)
    return new_lst

print (get_last_non_empty(l))
# input ->[None , None , None ,None ,10, 1, 2, 3, None, 4, None, None] 
# output ->[10, 10, 10, 10, 10, 1, 2, 3, 3, 4, 4, 4] 

请注意,列表开头的夜晚有多个None值。 这两个功能可以处理这种情况

答案 5 :(得分:0)

一种非常简单且基本的解决方案

lis = []
var = a[0]
for i in a:
    if i:
        lis.append(i)
        var = i
    elif i != 0:
        lis.append(var)
    else:
        lis.append(i)
添加了

var = a[0]只是为了消除Out of range错误。上面的代码输出[None, 1, 2, 3, 3, 4, 4, 4]。遍历列表a;如果值是non-None,则将其添加到列表中,否则,它将添加存储在var变量中的最后一个non-None值。对于第一个元素为None的情况,添加最后一个else,然后将None按原样添加到列表中。