Python way to iterate over a biased list of tuples

Given a list L = [('a',3),('b',4),('c',14),('d',10)]

, the desired output is the first element from the tuple, and the second element from the following set, for example:

a 4
b 14
c 10

      

A simple but fearless way would be

for i in range(len(L)-1):
    print(L[i][0], L[i+1][1])

      


Alternatively, this is what I came up with:

for (a0,a1),(b0,b1) in zip(L,L[1:]):
    print(a0,b1)

      

but it seems wasteful. Is there a standard way to do this?

+3


source to share


4 answers


To improve on the example zip

(which is already good) you can use itertools.islice

to avoid creating a sliced ​​copy of the original list. In python 3, the code below only generates values, no temporary list is created in this process.



import itertools

L = [('a',3),('b',4),('c',14),('d',10)]


for (a0,_),(_,b1) in zip(L,itertools.islice(L,1,None)):
    print(a0,b1)

      

+1


source


I personally think both are great. You can extract elements and attach to them:



pairs = zip(map(itemgetter(0), L), map(itemgetter(1), L[1:]))
# [('a', 4), ('b', 14), ('c', 10)]

      

+2


source


The Python way is to use a generator expression.

You can write it like this:

for newTuple in ((L[i][0], L[i+1][1]) for i in range(len(L)-1)):
  print(newTuple)

      

It looks like a list comprehension, but the iterator-generator will not create a complete list, it just produces a tuple by tuple, so it does not take extra memory for a complete copy of the list.

+2


source


I would split the first and second elements with two generator expressions, use islice to remove one element, and pin the two streams again.

first_items = (a for a, _ in L)
second_items = (b for _, b in L)
result = zip(first_items, islice(second_items, 1, None))

print(list(result))
# [('a', 4), ('b', 14), ('c', 10)]

      

0


source







All Articles