create tuple from ranges in python

Question:

Is there a way in python to create a tuple of months and years (as: [(2020, 1),(2020,2)...] ) by using the tuple() function?

My code:

monthyears = []
for y in range(2020,2017,-1):
    if y == 2018:
        m_end = 6
    else:
        m_end = 0
    for m in range(12,m_end,-1):
        monthyears.append((y,m))

output:

[(2020, 12),
 (2020, 11),
 (2020, 10),
 (2020, 9),
 (2020, 8),
 (2020, 7),
 (2020, 6),
 (2020, 5),
 (2020, 4),
 (2020, 3),
 (2020, 2),
 (2020, 1),
 (2019, 12),
 (2019, 11),
 (2019, 10),
 (2019, 9),
 (2019, 8),
 (2019, 7),
 (2019, 6),
 (2019, 5),
 (2019, 4),
 (2019, 3),
 (2019, 2),
 (2019, 1),
 (2018, 12),
 (2018, 11),
 (2018, 10),
 (2018, 9),
 (2018, 8),
 (2018, 7)]

for loops are fine, but I’d like to learn a new trick, if it exists.

Asked By: bearcub

||

Answers:

Try this:

>>> tuple((y, m) for y in range(2020, 2017, -1) for m in range(12, (6 if y == 2018 else 0), -1))

# you can use 'in' if you want to check multi-year
# >>> tuple((y, m) for y in range(2020, 2017, -1) for m in range(12, (6 if y == 2018 else 0), -1))

((2020, 12),
 (2020, 11),
 (2020, 10),
 (2020, 9),
 (2020, 8),
 (2020, 7),
 (2020, 6),
 (2020, 5),
 (2020, 4),
 (2020, 3),
 (2020, 2),
 (2020, 1),
 (2019, 12),
 (2019, 11),
 (2019, 10),
 (2019, 9),
 (2019, 8),
 (2019, 7),
 (2019, 6),
 (2019, 5),
 (2019, 4),
 (2019, 3),
 (2019, 2),
 (2019, 1),
 (2018, 12),
 (2018, 11),
 (2018, 10),
 (2018, 9),
 (2018, 8),
 (2018, 7))
Answered By: I'mahdi

you can use modulo arithmetic to process the range as a year-month offset and back to a tuple in the output:

start = 2020 * 12 + 12    # Year * 12 + month
stop  = 2018 * 12 + 6
monthyears = [ (ym//12,ym%12+1) for ym in range(start-1,stop-1,-1) ]
     

output:

print(*monthyears,sep="n")

(2020, 12)
(2020, 11)
(2020, 10)
(2020, 9)
(2020, 8)
(2020, 7)
(2020, 6)
(2020, 5)
(2020, 4)
(2020, 3)
(2020, 2)
(2020, 1)
(2019, 12)
(2019, 11)
(2019, 10)
(2019, 9)
(2019, 8)
(2019, 7)
(2019, 6)
(2019, 5)
(2019, 4)
(2019, 3)
(2019, 2)
(2019, 1)
(2018, 12)
(2018, 11)
(2018, 10)
(2018, 9)
(2018, 8)
(2018, 7)

I’m not sure how you expect the tuple constructor to be helpful here. Tuples can be compared so, in a way, it may be helpful to work with tuples directly as the filtering condition:

start = (2020,12)
stop  = (2018,6)

monthyears = [ (y,m) for y in range(start[0],stop[0]-1,-1)
                     for m in range(12,0,-1)
                     if end < (y,m) <= start ]
Answered By: Alain T.

You can simply do this

for y in range(2017, 2021):
    for m in range(1,13):
        myList.append((y, m))

output

[(2017, 1) 

(2017, 2)

(2017, 3)

(2017, 4)

(2017, 5)

(2017, 6)

(2017, 7)

(2017, 8)
...)]
Answered By: Ghassen Jemaî
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.