复制非零值列表以填充另一个列表的零的Pythonic方法
这是我想放入另一个列表中的数字列表,替换所有零值复制非零值列表以填充另一个列表的零的Pythonic方法,python,list,Python,List,这是我想放入另一个列表中的数字列表,替换所有零值 a = [2, 5, 6, 3, 9] b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4] 下面是替换所有零值之前其他列表的外观 a = [2, 5, 6, 3, 9] b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4] 这样c将 c = [[2, 3, 9, 1, 3] [3, 3, 4, 2, 5] [3, 5, 5, 6, 2] [3,
a = [2, 5, 6, 3, 9]
b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4]
下面是替换所有零值之前其他列表的外观
a = [2, 5, 6, 3, 9]
b = [0, 7, 9, 3, 3, 0, 4, 0, 3, 1, 0, 0, 4]
这样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]]
一种方法是使用
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]
>>> 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]]
正如@bulbus所指出的,如果没有足够的零来填充,这将引发StopIteration异常。您可以使用next
的默认值,例如next(fill,0)
,如果您想避免这种情况
对于您的2D案例,同样的方法也适用,我们只需要更改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]
>>> 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]]
我相信在这种情况下,最简单、可读性最好的方法是:
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, 7, 9, 3, 3, 5, 4, 6, 3, 1, 3, 9, 4]
首先,让我们确保您的
a
系列足够长:
a_long = itertools.chain(a, itertools.repeat(0))
这将在耗尽原始a
后提供无尽的零
然后,我们将为该系列创建一个迭代器,以便有选择地提取next()
值:
a_iter = iter(a_long)
最后,使用a
系列的替换项生成b
,只要它们可用:
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=[2,5,6,3,9]
>>>b=[0,7,9,3,3,0,4,0,3,1,0,0,4,0,1,0,2]
>>>进口itertools
>>>a_long=itertools.chain(a,itertools.repeat(0))
>>>国际热核聚变实验堆=国际热核聚变实验堆(长)
>>>结果=(如果bval!=0,则bval!=下一个(a_iter)对于b中的bval)
>>>结果
>>>名单(结果)
>>> [2, 7, 9, 3, 3, 5, 4, 6, 3, 1, 3, 9, 4, 0, 1, 0, 2]
请注意,所有中间值(a_long,a_iter)都是可迭代的,因此它们可以处理超长系列而无需大量内存分配。结果是一个生成器,因此它一次只保留一个值。您可以使用numpy在适当的位置修改
b
(或者先将b
复制到c
,然后如果希望在c
中修改c
):
然后直接将a
的元素依次分配给b
中的每个元素,其中0
:
>>> 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
vals=iter(a)
for t in zip(*np.where(b==0)):
b[t]=next(vals, 0)
或者,您可以循环索引元组,其中b
为0,并指定a
中的下一个值或默认值:
>>> b[b==0]=a+[0]*(np.count_nonzero(b==0)-len(a))
^ 0 used as default for elements not found in a
vals=iter(a)
for t in zip(*np.where(b==0)):
b[t]=next(vals, 0)
如果零太多,此操作将失败
[x if x!=0 else next(fill,0)表示b中的x]
@bulbus:我倾向于选择错误而不是静默扩展,但你是对的,有些人感觉不一样。