I have a list of stings representing a month in a year (not sorted and not consecutive):
['1/2013', '7/2013', '2/2013', '3/2013', '4/2014', '12/2013', '10/2013', '11/2013', '1/2014', '2/2014']
I'm looking for a Pythonic way to sort all of them and separate each consecutive sequence as the following suggests:
[ ['1/2013', '2/2013', '3/2013', '4/2013'],
['7/2013'],
['10/2013', '11/2013', '12/2013', '1/2014', '2/2014']
]
Any ideas?
An easy solution in this specific case (not many elements) is just to iterate over all the months:
Based on the example from the docs that shows how to find runs of consecutive numbers using
itertools.groupby()
:The key to the solution is differencing with a range generated by
enumerate()
so that consecutive months all appear in same group (run).Output
The groupby examples are cute, but too dense and will break on this input:
['1/2013', '2/2017']
, i.e. when there are adjacent months from non-adjacent years.Result:
If you wants to just sort your list then use sorted function and pass
key
value = a function that converts date-string into Python'sdatetime
object aslambda d: datetime.strptime(d, '%m/%Y')
, check following code example for your list asL
:To split "list of month/year strings" into "list of list of consecutive months", you can use following script (read comments), In which, first I sorted the list
L
then groups strings on the basis of consecutive month (to check consecutive month I written a function):It works as follows:
Code to split your code:
Don't forget to include
from datetime import datetime
, This trick I believe you can easily update for a new list of dates in which dates are in other format.After @9000 hint I could simplified my sorted function and removed old answer if you wants to check old script check @codepad.
Well, here's one without itertools and as short as I could make it without hurting readability. The trick is in use of
zip
. It's basically @moe's answer unwrapped a bit.Trying it:
We could save a bit of performance and cognitive load if we mapped
parseAsPair
over the list in the very end. Then every invocation ofparseAsPair
could be removed fromgroupSequentially
, but we'd have to transform the result to strings again.