Iterating over a list of lists and comparing current and recent items

Sorry if this is already covered in another thread. I'm a bit new to Python (3 in particular), so maybe the answer was given conceptually to a similar question and I missed the relevance.

I am going through a list of lists similar to the following:

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]]

      

I would like to conditionally perform certain actions whenever the third item in a given sublist differs from the third item in the previous sublist. In the example above, this will happen for the third sublist (y! = X), the fifth subexpression (z! = Y), and the sixth subexpression (x! = Z).

Whenever such inconsistencies occur, I would like to change the corresponding first item in the current sublist. (Note: I know that I usually don't change the list while iterating through it, but I find it okay to change other elements of the list of the list [as opposed to adding or removing entries]. For example, in the above situation, I would like the loop created the following modified large list:

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]]

      

After spending a few hours playing around with the index and browsing through other topics, I am still stuck. Any help would be really appreciated.

+3


source to share


3 answers


The following code achieves the desired result:

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)

      



Using python 3.4.1

+2


source


To iterate over pairs of elements, I usually do this:

for x,y in zip(biglist, itertools.islice(biglist, 1, None)):
    print(x, y)

      

From there, you compare the third elements of the two lists and update the first element of the first list if they are not the same:



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)

      

Output:

[['a', 'b', 'x', 'd'],
 ['a', 'b', 'x', 'd'],
 ['newa', 'b', 'y', 'd'],
 ['a', 'b', 'y', 'd'],
 ['newa', 'b', 'z', 'd'],
 ['newa', 'b', 'x', 'd']]

      

+1


source


Use two separate iterators. It's not often you create an iterator on a list explicitly, as opposed to having a loop for

create it implicitly, but here's a case where it's useful.

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]

      

You are correct that it is safe to modify the sublist while iterating over the outer list, because the outer list itself does not change.

You can also use itertools.islice

(as suggested by Raymond Hettinger) instead of manually using the first element of the second iterator.

from itertools import izip, islice
for prev, curr in izip(biglist, islice(biglist, 1, None)):

      

0


source







All Articles