遍历列表中的列表并比较当前元素和上一个元素
抱歉如果这个问题在其他讨论中已经被提到过。我对Python(特别是3版)还比较陌生,所以可能我没有理解类似问题的答案。
我正在遍历一个包含多个列表的列表,类似下面这样:
biglist = [[a, b, x, d], [a, b, x, d], [a, b, y, d], [a, b, y, d], [a, b, z, d], [a, b, x, d]]
我想在每当某个子列表的第三个元素和前一个子列表的第三个元素不同时,执行一些特定的操作。在上面的例子中,这种情况会发生在第三个子列表(y != x)、第五个子列表(z != y)和第六个子列表(x != z)。
每当出现这种不匹配的情况时,我想修改当前子列表中的第一个元素。(注意 - 我知道在遍历列表时一般不应该改变它,但我认为可以修改列表中的其他元素,而不是添加或删除条目。例如,在上面的情况中,我希望循环能生成以下修改后的大列表:
biglist = [[a, b, x, d], [a, b, x, d], [new_a, b, y, d], [a, b, y, d], [new_a, b, z, d], [new_a, b, x, d]]
经过几个小时的尝试和阅读其他讨论,我还是卡住了。任何帮助都会非常感激。
3 个回答
0
使用两个独立的迭代器。通常情况下,我们不会显式地在列表上创建迭代器,而是让一个for
循环自动创建,但在这里,这样做是有用的。
iter1 = iter(biglist)
iter2 = iter(biglist)
next(iter2) # advance the second iterator
for prev, curr in itertools.izip(iter1, iter2):
if prev[2] != curr[2]:
curr[0] = 'new_' + curr[0]
你说得对,在遍历外部列表时修改子列表是安全的,因为外部列表本身并没有被改变。
你也可以使用itertools.islice
(正如Raymond Hettinger所建议的)来代替手动消耗第二个迭代器的第一个元素。
from itertools import izip, islice
for prev, curr in izip(biglist, islice(biglist, 1, None)):
1
为了遍历一对一对的元素,我通常会这样做:
for x,y in zip(biglist, itertools.islice(biglist, 1, None)):
print(x, y)
接下来,你需要比较两个列表的第三个元素,如果它们不相同,就更新第二个列表的第一个元素:
import itertools
biglist = [['a', 'b', 'x', 'd'], ['a', 'b', 'x', 'd'], ['a', 'b', 'y', 'd'], ['a', 'b', 'y', 'd'], ['a', 'b', 'z', 'd'], ['a', 'b', 'x', 'd']]
for x,y in zip(biglist, itertools.islice(biglist, 1, None)):
if x[2] != y[2]:
y[0] = 'new' + y[0]
import pprint
pprint.pprint(biglist)
输出结果:
[['a', 'b', 'x', 'd'],
['a', 'b', 'x', 'd'],
['newa', 'b', 'y', 'd'],
['a', 'b', 'y', 'd'],
['newa', 'b', 'z', 'd'],
['newa', 'b', 'x', 'd']]
2
以下代码可以实现你想要的效果:
biglist = [['a', 'b', 'x', 'd'],
['a', 'b', 'x', 'd'],
['a', 'b', 'y', 'd'],
['a', 'b', 'y', 'd'],
['a', 'b', 'z', 'd'],
['a', 'b', 'x', 'd']]
for i in range(len(biglist)):
if i > 0:
if biglist[i][2] != biglist[i-1][2]:
biglist[i][0] = 'new_' + biglist[i][0]
print(biglist)
使用的是 Python 3.4.1 版本