使用前面的非None项替换python列表中的None值?

时间:2015-09-11 17:01:52

标签: python list

我有一个名为Headings的python列表:

Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]

我想得到的是None值被替换为前面的字符串或数字,并且最接近None值,如下所示:

Headings=['Doug', 'Doug', 'Doug', 'Doug', 'Doug', 1234, 1234, 1234, 'Mike', 'Mike']

我该怎么做?

还有最初的标题清单..

Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]

如何获取字符串或数字开始位置以及结束位置的索引?

例如,我需要'Doug'所在的索引以及1234之前的None的索引。 同样,我需要1234所在的索引和'Mike'之前的最后一个的索引。

4 个答案:

答案 0 :(得分:0)

使用在遇到None时返回最后一个非None值的生成器:

def replace_none(lst):
    last = None
    for item in lst:
        if item is None:
            yield last
        else:
            last = item
            yield item

如果您需要列表,只需在生成器上调用list()

>>> def replace_none(lst):
...     last = None
...     for item in lst:
...         if item is None:
...             yield last
...         else:
...             last = item
...             yield item
... 
>>> Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]
>>> list(replace_none(Headings))
['Doug', 'Doug', 'Doug', 'Doug', 'Doug', 1234, 1234, 1234, 'Mike', 'Mike']

答案 1 :(得分:0)

from itertools import accumulate

Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]

Headings = accumulate(Headings,lambda x, y: x if y is None else y)
['Doug', 'Doug', 'Doug', 'Doug', 'Doug', 1234, 1234, 1234, 'Mike', 'Mike']

如果您还想要索引,则可以使用此answer的变体:

from itertools import chain
Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]

def replace_none(l):
    inds = ((ind, ele) for ind, ele in enumerate(Headings) if ele is not None)
    start_i, start_ele = next(inds)
    yield start_i
    yield from chain.from_iterable(((i-1, i) for i, _ in inds))
    for ind, ele in enumerate(l):
        if ele is None:
            Headings[ind] = start_ele
        else:
            start_ele = ele

输出:

print(list(replace_none(Headings)))

print(Headings)
[0, 4, 5, 7, 8]
['Doug', 'Doug', 'Doug', 'Doug', 'Doug', 1234, 1234, 1234, 'Mike', 'Mike']

如果第一个元素可能是None,并且您希望在第一个不是None的元素之前使用前一个None:

def replace_none(l):
    inds = ((ind, ele) for ind, ele in enumerate(Headings) if ele is not None)
    start_i, start_ele = next(inds)
    if start_i == 0:
        yield start_i
    else:
        yield from (start_i-1, start_i)
    yield from chain.from_iterable(((i-1, i) for i, _ in inds))
    for ind, ele in enumerate(l):
        if ele is None:
            Headings[ind] = start_ele
        else:
            start_ele = ele

答案 2 :(得分:0)

您可以使用生成器来实现此目的。关于它们如何工作的一个很好的解释发布在这里:What does the "yield" keyword do in Python?

那就是说,问题第一部分的简明方法如下:

def replace_none(lis):
    last = None
    for item in lis:
        last = last if item is None else item
        yield last

如果需要,您可以将生成器强制转换为列表,如其他答案中所述:

Headings = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None]
list(replace_none(Headings))

答案 3 :(得分:0)

此解决方案没有成功-想知道我是否在程序中缺少任何复杂性?

def replaceNone(myList):
    
    for idx,value in enumerate(myList):
        if value == None:
            myList[idx] = myList[idx-1]
            
    return myList

myList = ['Doug', None, None, None, None, 1234, None, None, 'Mike', None] 
print(replaceNone(myList))

['Doug', 'Doug', 'Doug', 'Doug', 'Doug', 1234, 1234, 1234, 'Mike', 'Mike']