和b。我想删除列表b中的所有数字,其中有一个' 0'以及与b中的零共享相同索引的相应数字。 这是我的代码:
a = [ 1 , 23 , 3 , 45 , 5 , 63 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15]
b = [ 8 , 0 , 0 , 7 , 0 , 9 , 3 , 2 , 4 , 13 , 25 , 45 , 34 , 25 , 11]
indexzeroes = [i for i, j in enumerate(b) if j == 0]
for i in indexzeroes:
b.pop(i)
a.pop(i)
print a
print b
但是我得到了a和b的错误更新列表。我已经确定了原因是在' for循环中' for循环'每次我弹出' pop'我都改变了列表结构。一个项目,以便剩余零的索引也发生变化。
对于这样一个表面上简单的问题,这似乎很复杂。有人可以帮忙吗?
答案 0 :(得分:5)
原因是当您从pop
或i
a
b
索引时,所有元素都会向左移动一次。您可以通过反向弹出项目来解决此问题(因为索引应按排序顺序):
for i in reversed(indexzeroes):
a.pop(i)
b.pop(i)
Wit说,对于大型列表来说这可能有些低效(最坏情况为O(n ^ 2))。您最好使用set
,它会以一点额外内存为代价提供O(n)
算法:
indexzeroes = {i for i, j in enumerate(b) if j == 0}
a = [x for i, x in enumerate(a) if i not in indexzeros]
b = [x for i, x in enumerate(b) if i not in indexzeros]
答案 1 :(得分:1)
如果从列表末尾开始,则可以删除:
for ind in range(len(a) - 1, -1, -1):
if b[ind] == 0:
del a[ind]
del b[ind]
输出:
[1, 45, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
[8, 7, 9, 3, 2, 4, 13, 25, 45, 34, 25, 11]
从结尾开始工作,因为列表越来越小,所以我们尚未看到的任何元素仍将处于相同的索引,因为索引比我们目前为止看到的任何东西都要小。如果你想要使用它返回的元素,你也应该只使用list.pop
,如果你只想删除那么list.remove
或del
,那将是最好的。
您也可以在O(n)
时使用套装,通过创建新列表来执行此操作:
a = [1, 23, 3, 45, 5, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
b = [8, 0, 0, 7, 0, 9, 3, 2, 4, 13, 25, 45, 34, 25, 11]
from itertools import izip
def remove_(i,l1,l2):
c,d = [], []
for j, k in izip(l1, l2):
if k != i:
c.append(j),d.append(k)
return c, d
a, b= remove_(0, a, b)
print(a,b)
答案 2 :(得分:1)
作为替代方法,您可以使用列表推导,如下所示:
a = [1, 23, 3, 45, 5, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
b = [8, 0 , 0, 7 , 0, 9 , 3, 2, 4, 13, 25, 45, 34, 25, 11]
a_out = []
b_out = []
[(a_out.append(v1), b_out.append(v2)) for v1, v2 in zip(a,b) if v2]
print a_out
print b_out
这将显示以下内容:
[1, 45, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
[8, 7, 9, 3, 2, 4, 13, 25, 45, 34, 25, 11]
如果列表很大,您也可以切换为使用itertools.izip
而不是zip
。
或者按照建议,使用香草for-loop
:
a = [1, 23, 3, 45, 5, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
b = [8, 0 , 0, 7 , 0, 9 , 3, 2, 4, 13, 25, 45, 34, 25, 11]
a_out = []
b_out = []
for v1, v2 in zip(a,b):
if v2:
a_out.append(v1)
b_out.append(v2)
print a_out
print b_out
答案 3 :(得分:0)
另一种方法,您可以使用过滤器功能。 # 它使代码单行:)
这是给你的代码..
a = [1, 23, 3, 45, 5, 63, 7, 8, 9, 10, 11, 12, 13, 14, 15]
b = [8, 0, 0, 7, 0, 9, 3, 2, 4, 13, 25, 45, 34, 25, 11]
print(list(filter(lambda x: x[0] and x[1], zip(a, b))))