我做了一个应该删除列表列表中任何类似事件的函数,但我对以下错误感到惊讶:IndexError:列表索引超出范围,为什么会这样?
例如:
input: [['a0', 'a3'], ['a1', 'a2'], ['a0', 'a3'], ['a2', 'a1'], ['a3', 'a1']] expected output:[['a0', 'a3'], ['a1', 'a2'], ['a3', 'a1']]
def getList(a):
b=a
lena = len(a)
print(len(a))
for i in range(lena):
for j in range (i+1,lena):
print(i,j)
print(a[i],a[j])
if(a[i][0],a[i][1])==(a[j][1],a[j][0]) or (a[i][0],a[i][1])==(a[j][0],a[j][1]):
print(a)
a = [['a0', 'a3'], ['a1', 'a2'], ['a0','a3'], ['a2','a1'], ['a3', 'a1']]
getList(a)
输出:
[['a0', 'a3'], ['a1', 'a2'], ['a0', 'a3'], ['a2', 'a1'], ['a3', 'a1']]
5
0 1
['a0', 'a3'] ['a1', 'a2']
0 2
['a0', 'a3'] ['a0', 'a3']
[['a0', 'a3'], ['a1', 'a2'], ['a0', 'a3'], ['a2', 'a1'], ['a3', 'a1']]
0 3
['a0', 'a3'] ['a2', 'a1']
0 4
['a0', 'a3'] ['a3', 'a1']
1 2
['a1', 'a2'] ['a0', 'a3']
1 3
['a1', 'a2'] ['a2', 'a1']
[['a0', 'a3'], ['a1', 'a2'], ['a0', 'a3'], ['a2', 'a1'], ['a3', 'a1']]
1 4
['a1', 'a2'] ['a3', 'a1']
2 3
['a0', 'a3'] ['a2', 'a1']
2 4
['a0', 'a3'] ['a3', 'a1']
3 4
['a2', 'a1'] ['a3', 'a1']
当我通过添加b.pop(j)或诸如此类的任何东西来修改代码时:
def getList(a):
b=a
lena = len(a)
print(len(a))
for i in range(lena):
for j in range (i+1,lena):
print(i,j)
print(a[i],a[j])
if(a[i][0],a[i][1])==(a[j][1],a[j][0]) or (a[i][0],a[i][1])==(a[j][0],a[j][1]):
print(a)
b.pop(j)
a = [['a0', 'a3'], ['a1', 'a2'], ['a0','a3'], ['a2','a1'], ['a3', 'a1']]
getList(a)
结果:
5
0 1
['a0', 'a3'] ['a1', 'a2']
0 2
['a0', 'a3'] ['a0', 'a3']
[['a0', 'a3'], ['a1', 'a2'], ['a0', 'a3'], ['a2', 'a1'], ['a3', 'a1']]
0 3
['a0', 'a3'] ['a3', 'a1']
0 4
Traceback (most recent call last):
File "C:/Users/I/Desktop/papers/test.py", line 21, in <module>
getList(a)
File "C:/Users/I/Desktop/papers/test.py", line 13, in getList
print(a[i],a[j])
IndexError: list index out of range
我想知道可能是什么问题?
答案 0 :(得分:1)
在迭代列表时处理列表是灾难的根源,并且几乎总是可以避免的,方法是将结果累加到一个单独的结构上,或者至少为迭代目的复制原始列表(b = a
别名,而不是副本,可以使用a.copy()
或a[:]
完成)。 pop
时,列表长度发生变化,并且迭代器引用不存在的列表元素。
此外,最好不要将打印与程序输出混淆。大多数算法的结果都不应为标准输出。相反,应将结果写入数据结构,并返回给调用者,以供调用者根据需要使用或转储。
另一个问题是效率:嵌套循环意味着O(n 2 )运行时间。使用多余的空间可以为您提供线性算法。
如果将每个子列表转换为元组,则它们将成为可散列的,并且可以将数据粘贴到set
中以消除重复项,然后将所有内容转换回列表:
>>> [list(x) for x in set(tuple(sorted(x)) for x in a)]
[['a1', 'a2'], ['a1', 'a3'], ['a0', 'a3']]
问题是订单丢失。如果应该保留顺序,则可以使用一组作为查找表:
>>> lookup = set()
>>> result = []
>>> for pair in a:
... key = tuple(sorted(pair))
... if key not in lookup:
... lookup.add(key)
... result.append(pair)
...
>>> result
[['a0', 'a3'], ['a1', 'a2'], ['a3', 'a1']]
如果您使用的是CPython 3.6+,则可以利用dictionary ordering来改进上面显示的set
方法:
>>> [list(x) for x in dict([tuple(sorted(x)), None] for x in a)]
[['a0', 'a3'], ['a1', 'a2'], ['a1', 'a3']]
3.6之前的版本可以使用collections.OrderedDict
获得相同的结果:
>>> from collections import OrderedDict
>>> [list(x) for x in OrderedDict([tuple(sorted(x)), None] for x in a)]
[['a0', 'a3'], ['a1', 'a2'], ['a1', 'a3']]
答案 1 :(得分:1)
如果您调用b = a.copy()
并返回b,则您的代码可以正常工作。
b = a
表示变量名b指向与a相同的Object(list)。