简体   繁体   中英

How to sort a list in Python based on a set of keys in different levels

I have a list of dictionaries in python . I want to sort it by key s ie, first by chain_id , then by start.residue_number and then by end.residue_number . In the list below, the 4th and 6th element should be coming the other way around. I could use sorted with from operator import itemgetter, attrgetter to sort on chain_id , but how to do same with a dictionary inside dictionary ?

            "mappings": [
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 63
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "A",
                    "struct_asym_id": "A"
                },
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 116
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "A",
                    "struct_asym_id": "A"
                },
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 124
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "A",
                    "struct_asym_id": "A"
                },
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 116
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "B",
                    "struct_asym_id": "B"
                },
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 124
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "B",
                    "struct_asym_id": "B"
                },
                {
                    "entity_id": 1,
                    "end": {
                        "residue_number": 63
                    },
                    "start": {
                        "residue_number": 1
                    },
                    "chain_id": "B",
                    "struct_asym_id": "B"
                }
            ]

I assumed d as your dict, Solved with sorted and lambda

# Sort with chain_id
In [93]: sort_1 = sorted(d['mappings'],key=lambda x:x['chain_id'])
# Sort with start residue number
In [94]: sort_2 = sorted(sort_1,key=lambda x:x['start']['residue_number'])
# Sort with end residue number
In [95]: sort_3 = sorted(sort_2,key=lambda x:x['end']['residue_number'])

Or you can do in a line.

sorted(d['mappings'],key=lambda x:(x['chain_id'],x['start']['residue_number'],x['end']['residue_number']))

Inspired from leotrubach's answer.

If all of the keys are to be sorted in descending order you could use list.sort() or sorted() functions and create a tuple returning key function:

print(
    sorted(
        mappings, 
        key=lambda x: (
            x['chain_id'], 
            x['start']['residue_number'], 
            x['end']['residue_number']
        )
    )
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM