对于不更新的条件:python

对于不更新的条件:python,python,for-loop,Python,For Loop,我有一个需要逻辑的程序,比如改变每个循环的条件。请参阅代码以清楚地理解 节目: 我有两个列表,其中再次包含列表(a和b)。如果a子列表的第二个元素与b子列表的第二个元素匹配,则两者都必须删除 代码: a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']] b = [['c', 'b'], ['0', '2']] for i in range(0, len(a)): for j in range(0, len(b)):

我有一个需要逻辑的程序,比如改变每个循环的条件。请参阅代码以清楚地理解

节目: 我有两个列表,其中再次包含列表(
a
b
)。如果
a
子列表的第二个元素与
b
子列表的第二个元素匹配,则两者都必须删除

代码:

a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
b = [['c', 'b'], ['0', '2']]

for i in range(0, len(a)):
    for j in range(0, len(b)):
        if a[i][1] == b[j][1]:
            del a[i]
            del b[j]
print(a)
print(b)
错误: 索引器。我能理解这是因为的条件

使用
break
continue
会变得越来越复杂。

那么,有什么其他解决方案吗?

问题是,当您删除一个项目(比如从
b
)时,范围已经确定,因此索引超出了范围

正如@RevanProdigalKnight所指出的,您可以通过向后迭代来解决这个问题:

a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
b = [['c', 'b'], ['0', '2']]

for i in range(len(a)-1,-1,-1):
    for j in range(len(b)-1,-1,-1):
        if a[i][1] == b[j][1]:
            del a[i]
            del b[j]
            break
print(a)
print(b)
如果要仅删除
b
中的一行(如果等效)

另一方面,如果您希望删除
b
中的所有副本,请尝试:

for i in range(len(a)-1,-1,-1):
    key = a[i][1]
    removed = 0
    for j in range(len(b)-1,-1,-1):
        if key == b[j][1]:
            del b[j]
            removed = 1
    if removed == 1
        del a[i]
print(a)
print(b)
差异?

假设您有两个数组:

a = [[0,0],[1,1],[2,2]]
b = [[0,0],[2,1],[3,0]]
然后使用第一种算法将导致:

a = [[2,2]]
b = [[0,0]]
a = [[2,2]]
b = []
而第二个将导致:

a = [[2,2]]
b = [[0,0]]
a = [[2,2]]
b = []

问题是,当您删除一个项目(比如从
b
)时,范围已经确定,因此索引超出范围

正如@RevanProdigalKnight所指出的,您可以通过向后迭代来解决这个问题:

a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
b = [['c', 'b'], ['0', '2']]

for i in range(len(a)-1,-1,-1):
    for j in range(len(b)-1,-1,-1):
        if a[i][1] == b[j][1]:
            del a[i]
            del b[j]
            break
print(a)
print(b)
如果要仅删除
b
中的一行(如果等效)

另一方面,如果您希望删除
b
中的所有副本,请尝试:

for i in range(len(a)-1,-1,-1):
    key = a[i][1]
    removed = 0
    for j in range(len(b)-1,-1,-1):
        if key == b[j][1]:
            del b[j]
            removed = 1
    if removed == 1
        del a[i]
print(a)
print(b)
差异?

假设您有两个数组:

a = [[0,0],[1,1],[2,2]]
b = [[0,0],[2,1],[3,0]]
然后使用第一种算法将导致:

a = [[2,2]]
b = [[0,0]]
a = [[2,2]]
b = []
而第二个将导致:

a = [[2,2]]
b = [[0,0]]
a = [[2,2]]
b = []

一种解决方案是跟踪要删除的索引,然后从最高索引开始,向下到最低索引删除它们

编辑:一个实现

a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
b = [['c', 'b'], ['0', '2']]

a_del = []
b_del = []

for i in range(0, len(a)):
    for j in range(0, len(b)):
        if a[i][1] == b[j][1]:
            a_del.append(i)
            b_del.append(j)

for idx in reversed(a_del):
    del a[idx]

for idx in reversed(b_del):
    del b[idx]

print(a)
print(b)

一种解决方案是跟踪要删除的索引,然后从最高索引开始,向下到最低索引删除它们

编辑:一个实现

a = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
b = [['c', 'b'], ['0', '2']]

a_del = []
b_del = []

for i in range(0, len(a)):
    for j in range(0, len(b)):
        if a[i][1] == b[j][1]:
            a_del.append(i)
            b_del.append(j)

for idx in reversed(a_del):
    del a[idx]

for idx in reversed(b_del):
    del b[idx]

print(a)
print(b)

通常的方法不是从循环中的列表中删除。不管怎么说,整个结构都相当低效。确定需要删除的元素,然后创建没有这些元素的新列表:

A = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
B = [['c', 'b'], ['0', '2']]

C = set(a[1] for a in A) & set(b[1] for b in B)

A = [a for a in A if a[1] not in C]
B = [b for b in B if b[1] not in C]

print(A)
print(B)

通常的方法不是从循环中的列表中删除。不管怎么说,整个结构都相当低效。确定需要删除的元素,然后创建没有这些元素的新列表:

A = [[1, 2, 3], ['a', 'b'], ['1', '2'], ['#', '$' '%']]
B = [['c', 'b'], ['0', '2']]

C = set(a[1] for a in A) & set(b[1] for b in B)

A = [a for a in A if a[1] not in C]
B = [b for b in B if b[1] not in C]

print(A)
print(B)
可能的解决办法

for data in zip(a,b):
if (data[0][1] == data[1][1]):
    #do whatever
可能的解决办法

for data in zip(a,b):
if (data[0][1] == data[1][1]):
    #do whatever


您正在修改列表的长度,同时对其原始长度进行迭代。你以为会发生什么?!修改列表是否重要?@jornsharpe。变量的长度发生了变化。所以对于条件也应该改变。但是它没有改变。@SGG
len(a)
只计算一次,当
for
循环开始时,作为
range
的一个参数-它不会在每次循环重复时更新。不建议在遍历列表时修改列表。您应该保存索引,并在循环后删除它们。您是在对列表的原始长度进行迭代时修改列表的长度。你以为会发生什么?!修改列表是否重要?@jornsharpe。变量的长度发生了变化。所以对于条件也应该改变。但是它没有改变。@SGG
len(a)
只计算一次,当
for
循环启动时,作为
range
的一个参数-它不会在每次循环重复时更新。不建议在遍历列表时修改列表。您应该保存索引并在循环后删除它们。这可以通过使用
range(len(object),0)向后迭代列表来解决,如果我没记错的话。但是,您必须将步骤设置为
-1
len(object)-1
,您也需要做一些事情来打破内部循环。如果有多个方程?多个方程,您可以简单地将它们合并在一起?这可以通过使用
范围(len(object),0)
向后迭代列表来解决,如果我没记错的话。但是,您必须将步骤设置为
-1
len(object)-1
,并且还需要做一些事情来打破内部循环。如果有多个等式呢?多个,您可以简单地将它们合并在一起?列表需要根据OP.@JamieCockburn进行适当修改,然后用新列表替换旧列表的内容
A[:]=…
。需要根据OP.@JamieCockburn修改列表,然后用新列表替换旧列表的内容
A[:]=…
。这需要复制我假定的值。这可能会非常耗费人力。@Hima原著将
a
中的每个元素与
b
中的每个元素进行比较,您的元素只在同一索引上配对,并且仅在两个列表中最短的一个长度内进行比较。@BlackJack+1表示您的答案!太好了。但是要求只在同一个指标上。。不需要比较all->all。@Hima如果这是要求,那么问题中的代码不会触发异常,因为不需要删除任何内容,OP也不会嵌套这两个循环。这需要复制我假设的值。这可能会非常耗费人力。@Hima原著将
a
中的每个元素与
b
中的每个元素进行比较,您的元素只在同一索引上配对,并且仅在两个列表中最短的一个长度内进行比较。@BlackJack+1表示您的答案!太好了。但是要求只在同一个指标上。。不需要比较all->all。@Hima如果这是要求,那么问题中的代码不会触发异常,因为不需要删除任何内容,OP也不会有嵌套