crust salty
crust salty

Reputation: 97

Sort nested list based on another sorted nested list python

I have a nested list in a list. In the first nested list, it has dates and in second, it has values corresponding to the date. I need to sort the date in the nested list. Based on date, corresponding value should be sorted. I know sorted(list) works. But I don't know how to sort the nested value list according to the date. I want the date type to be in string and not date. Help me with some solutions.

Here's the list:

a = [["2019-10-13","2019-10-12","2019-10-14","2019-10-11"],[10,28,5,37]]

Output Required

a = [["2019-10-11","2019-10-12","2019-10-13","2019-10-14"],[37,28,10,5]]

Upvotes: 0

Views: 418

Answers (4)

metasomite
metasomite

Reputation: 140

In the case where your date format might be variable, and sorting based on the string representation of the date may not produce the desired effects, using one of the datetime libraries (either directly or, for example, through pandas) will be more accurate.

It's not a one-liner, but could be more robust:

a = [["2019-10-13", "2019-10-12", "2019-10-14", "2019-10-11"], [10, 28, 5, 37]]


df = (
    pd.DataFrame(a, index=["date", "value"])
    .T.astype({"date": "datetime64", "value": "int"})
    .sort_values("date")
)

df["date"] = df["date"].apply(lambda x: str(x.date()))  # date as strings

output = [list(col) for col in df.T.values]

This gives the desired output as nested lists:

[['2019-10-11', '2019-10-12', '2019-10-13', '2019-10-14'], [37, 28, 10, 5]]

Upvotes: 2

s3dev
s3dev

Reputation: 9721

It's not a one-liner, but for those for whom pandas is their go-to:

import pandas as pd

a = [["2019-10-13","2019-10-12","2019-10-14","2019-10-11"],[10,28,5,37]]

df = pd.DataFrame({'dates': a[0], 'values':a[1]}).sort_values('dates')
b = [df['dates'].tolist()] + [df['values'].tolist()]

print(b)

Output:

This retains the [[list], [list]] structure from your question.

[['2019-10-11', '2019-10-12', '2019-10-13', '2019-10-14'], [37, 28, 10, 5]]

Upvotes: 2

Mohsen_Fatemi
Mohsen_Fatemi

Reputation: 3401

zip two lists, then sort them :

a = zip(["2019-10-13","2019-10-12","2019-10-14","2019-10-11"],[10,28,5,37])

after sorting the result would be :

>>> sorted(a)
[('2019-10-11', 37), ('2019-10-12', 28), ('2019-10-13', 10), ('2019-10-14', 5)]

Assign the sorted list to a variable, then unzip it :

>>> a = sorted(a)
>>> list(zip(*a))
[('2019-10-11', '2019-10-12', '2019-10-13', '2019-10-14'), (37, 28, 10, 5)]

Upvotes: 2

h4z3
h4z3

Reputation: 5478

Single line solution:

list(zip(*sorted(zip(*a), key=lambda x: x[0])))

Explanation:

  • zip(*a) makes pairs each date with its value
  • then we sort it by first element of the pair (key is function used to sort, x is single argument passed - in our case a pair, and we use x[0] to get the date)
  • we zip it back into dates and numbers respectively
  • and convert zip object into a list

Results:

>>> list(zip(*sorted(zip(*a), key=lambda x: x[0])))
[('2019-10-11', '2019-10-12', '2019-10-13', '2019-10-14'), (37, 28, 10, 5)]

Edit: I read your question fully and changed. I thought you were sorting dates by values, not the other way around, oops. Now it's correct (the result is the same).

Upvotes: 3

Related Questions