Pythonic复制非零值列表以填充另一个列表的零的方法

时间:2017-09-24 15:12:54

标签: python list

我有一个清单

a = [2, 5, 6, 3, 9]

这是其他列表应该是什么样子

b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4]

我想要实现的是将第一个列表复制到第二个列表中,这样它就会替换为零这样的零

c = [2, 7, 9, 3, 3, 5, 4, 6, 3, 1, 3, 9, 4]

如果b中有太多的零,它将被忽略并在c中保持为0,如果b中的零值太少,则某些值在不会被转移或复制到c

修改

并且有办法填写像这样的列表

b = [[0, 3, 9, 1, 3]
     [3, 3, 4, 2, 0]
     [3, 5, 5, 0, 2]
     [0, 0, 3, 8, 9]
     [1, 2, 3, 4, 5]]

以便c

c = [[2, 3, 9, 1, 3]
     [3, 3, 4, 2, 5]
     [3, 5, 5, 6, 2]
     [3, 9, 3, 8, 9]
     [1, 2, 3, 4, 5]]

4 个答案:

答案 0 :(得分:3)

一种方法是使用iter创建一个对象,逐个给出a中的每个元素,然后使用普通的listcomp:

>>> a = [2, 5, 6, 3, 9]
>>> b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4]
>>> fill = iter(a)
>>> c = [x if x != 0 else next(fill) for x in b]
>>> c
[2, 7, 9, 3, 3, 5, 4, 6, 3, 1, 3, 9, 4]

正如@bulbus指出的那样,如果你没有足够的零填充,这将引发一个StopIteration异常。您可以使用next的默认值,例如next(fill, 0)如果你想避免这种情况。

对于2D情况,相同的方法有效,我们只需要更改listcomp:

>>> fill = iter(a)
>>> b = [[0, 3, 9, 1, 3], [3, 3, 4, 2, 0], [3, 5, 5, 0, 2], [0, 0, 3, 8, 9], [1, 2, 3, 4, 5]]
>>> c = [[x if x != 0 else next(fill) for x in row] for row in b]
>>> c
[[2, 3, 9, 1, 3], [3, 3, 4, 2, 5], [3, 5, 5, 6, 2], [3, 9, 3, 8, 9], [1, 2, 3, 4, 5]]

答案 1 :(得分:0)

我相信在这种情况下,最简单,最易读的方法是最好的:

$('.download').on('click', function() {

    var $this = $(this);
    $this.button('loading');

    runMyScript(function() {
        $this.button('reset');
    });
);

输出:

a = [2, 5, 6, 3, 9]
b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4]
new_list = []
count = 0
for i in b:
    if i == 0:
       new_list.append(a[count])
       count += 1
    else:
       new_list.append(i)

答案 2 :(得分:0)

首先,让我们确保您的a系列足够长:

a_long = itertools.chain(a, itertools.repeat(0))

在耗尽原始a之后,这将提供无穷无尽的零。

然后,我们将为该系列创建一个迭代器,因此我们可以有选择地提取next()值:

a_iter = iter(a_long)

最后,只要有b系列中的替换,就生成a

result = (bval if bval != 0 else next(a_iter) for bval in b)

结果:

>>> a = [2, 5, 6, 3, 9]
>>> b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4, 0, 1, 0, 2]

>>> import itertools
>>> a_long = itertools.chain(a, itertools.repeat(0))
>>> a_iter = iter(a_long)

>>> result = (bval if bval != 0 else next(a_iter) for bval in b)
>>> result
<generator object <genexpr> at 0x10aab1af0>
>>> list(result)
>>> [2, 7, 9, 3, 3, 5, 4, 6, 3, 1, 3, 9, 4, 0, 1, 0, 2]

请注意,所有中间值(a_long,a_iter)都是可迭代的,因此它们可以处理超长序列而无需大量内存分配。结果是一个生成器,所以它一次只保留一个值。

答案 3 :(得分:0)

您可以使用numpy来修改b(或先将b复制到c,然后根据c修改c

import numpy as np 

a = [2, 5, 6, 3, 9]
b = np.array(b)

然后将a的元素直接分配给b0所在的每个元素:

>>> b[b==0]=a     # len(a)>=the number of 0's in this case...

或者,构建一个a元素列表或默认值:

>>> b[b==0]=a+[0]*(np.count_nonzero(b==0)-len(a))
               ^             0 used as default for elements not found in a

或者,您可以循环b为0的索引元组,并指定a的下一个值或默认值:

vals=iter(a)
for t in zip(*np.where(b==0)):
    b[t]=next(vals, 0)