在Python中过滤列表,然后对其进行过滤

时间:2014-05-27 02:10:25

标签: python

我有一个Python项目列表(v2.7但v2 / v3兼容解决方案会很好),例如:

a = [1,6,5,None,5,None,None,1]

我想过滤掉None值,然后对结果列表做一些事情,例如:

b = [x for x in a if x is not None]
c = f(b)

然后我想将None值放回原始索引中:

d = # ??? should give me [c[0],c[1],c[2],None,c[3],None,None,c[4]]

我需要立即将整个过滤列表传递给函数f()。我想知道是否有一种优雅的方式来做到这一点,因为到目前为止我所有的解决方案都很混乱。这是我迄今为止最干净的一个:

d = c
for i in range(len(a)):
    if not a[i]:
        d.insert(i, None)

编辑:修复列表理解中的拼写错误。

4 个答案:

答案 0 :(得分:8)

这是一个简单的解决方案,似乎可以解决这个问题:

>>> a = [1,6,5,None,5,None,None,1]
>>> b = [x for x in a if x is not None]
>>> c = [2,12,10,10,2]  # just an example
>>> 
>>> v = iter(c)
>>> [None if x is None else next(v) for x in a]
[2, 12, 10, None, 10, None, None, 2]

答案 1 :(得分:2)

a = [1,6,5,None,5,None,None,1]
b = [x for x in a if a is not None]
c = f(b)
d = [x if x is None else c.pop(0) for x in a]

答案 2 :(得分:1)

j = 0
d = []
for x in a:
    if x is None:
        d.append(None)
    else:
        d.append(c[j])
        j=j+1

答案 3 :(得分:1)

让我们试着跟踪非None的去向:

>>> def f(seq):
...     return [x+x for x in seq]
>>> a = [1,6,5,None,5,None,None,1]
>>> indices, filtered = zip(*[(i, v) for i,v in enumerate(a) if v is not None])
>>> indices
(0, 1, 2, 4, 7)
和以前一样:

>>> filtered
(1, 6, 5, 5, 1)
>>> mapped = f(filtered)
>>> mapped
[2, 12, 10, 10, 2]

从这里开始,我们可以做出一个稀疏的"从指数列出及其相应的产出:

>>> unfiltered = dict(zip(indices, mapped))
>>> unfiltered
{0: 2, 1: 12, 2: 10, 4: 10, 7: 2}

然后我们可以通过检查每个索引位置扩展为非稀疏版本:

>>> result = [unfiltered.get(i) for i in range(len(a))]
>>> result
[2, 12, 10, None, 10, None, None, 2]