How to cycle through a list and add one item to each tuple in a list of tuples using 'zip()'?

531 Views Asked by At

My data file contains eight thousand lines, where each line is a tuple. The first two lines are:

(2000, 1, 1, 1, 336)
(2000, 1, 1, 2, 335)

I would like to repeatedly cycle through the weekdays and append a weekday to each data tuple. The list of lines should look like:

[(2000, 1, 1, 1, 336, 'Sat'), (2000, 1, 1, 2, 335, 'Sun'), ...]

I've tried different approaches, and have managed to get almost every possible combination except the desired one. I can't quite wrap my head around what I've misunderstood.

Code

weekdays = ['Sat','Sun','Mon','Tue','Wed','Thu','Fri']    
a = read_file('VIK_sealevel_2000.txt')
zipp = list(zip(a, weekdays))
print(zipp[0:2])   

Output

[((2000, 1, 1, 1, 335), 'Sat'), ((2000, 1, 1, 2, 336), 'Sun')]
2

There are 2 best solutions below

0
On BEST ANSWER

The first problem is how to efficiently cycle through the weekdays. A clean solution is to use itertools.cycle().

The following will generate an infinite sequence of repeating weekdays.

import itertools

weekdays = ['Sat','Sun','Mon','Tue','Wed','Thu','Fri']
itertools.cycle(weekdays)

The zip() function will stop when the shortest input iterable is exhausted. Now that we have an infinite sequence of weekdays, the shortest input will be the eight thousand lines of data.

>>> import itertools
>>> weekdays = ['Sat','Sun','Mon','Tue','Wed','Thu','Fri']
>>> data = [(2000, 1, 1, 1, 336), (2000, 1, 1, 2, 335), (2000, 1, 1, 1, 334), 
            (2000, 1, 1, 2, 333), (2000, 1, 1, 1, 332), (2000, 1, 1, 2, 331), 
            (2000, 1, 1, 1, 330), (2000, 1, 1, 2, 329), (2000, 1, 1, 1, 328), 
            (2000, 1, 1, 2, 327)]
>>> list(zip(data, itertools.cycle(weekdays)))
[((2000, 1, 1, 1, 336), 'Sat'), ((2000, 1, 1, 2, 335), 'Sun'), 
 ((2000, 1, 1, 1, 334), 'Mon'), ((2000, 1, 1, 2, 333), 'Tue'), 
 ((2000, 1, 1, 1, 332), 'Wed'), ((2000, 1, 1, 2, 331), 'Thu'), 
 ((2000, 1, 1, 1, 330), 'Fri'), ((2000, 1, 1, 2, 329), 'Sat'), 
 ((2000, 1, 1, 1, 328), 'Sun'), ((2000, 1, 1, 2, 327), 'Mon')]

Lastly, to get the weekday inside the inner tuples, we can create new tuples within a list comprehension.

>>> [t + (day,) for t, day in zip(data, itertools.cycle(weekdays))]
[(2000, 1, 1, 1, 336, 'Sat'), (2000, 1, 1, 2, 335, 'Sun'), 
 (2000, 1, 1, 1, 334, 'Mon'), (2000, 1, 1, 2, 333, 'Tue'), 
 (2000, 1, 1, 1, 332, 'Wed'), (2000, 1, 1, 2, 331, 'Thu'), 
 (2000, 1, 1, 1, 330, 'Fri'), (2000, 1, 1, 2, 329, 'Sat'), 
 (2000, 1, 1, 1, 328, 'Sun'), (2000, 1, 1, 2, 327, 'Mon')]

Here, t is the tuple associated with each line of data, day is the weekday, and the syntax t + (day,) creates a new tuple formed by combining the data tuple with the weekday.

0
On

To add the weekday into each tuple, try using:

a = [(2000, 1, 1, 1, 335), (2000, 1, 1, 2, 336)] # was read_file('VIK_sealevel_2000.txt')
weekdays = ['Sat','Sun','Mon','Tue','Wed','Thu','Fri']
zipp = [row[0] + (row[1],) for row in zip(a, weekdays)]

UPDATE:

As pointed out in another answer by Christopher Peisert, this answer is incorrect when there are more rows in a than in weekdays