-2

I have a list of dictionaries where the order of the keys is not consistent. Ideally I would like 'vid' to always come first with 'name' being second. As you can see below, sometimes 'name' comes first. How can I sort this list of dictionaries to always have 'vid' first?

viri_assets = [
    {'vid': 'transpower_036', 'name': '221_02_PB_520_REF_174050'},
    {'name': '242_07_DINA_HSTLR_YT_210238', 'vid': 'transpower_168'},
    {'vid': 'transpower_170', 'name': '242_08_DINA_HSTLR_YT_210220'},
    {'name': '251_PS04_PB_520_REF_109968', 'vid': 'transpower_166'},
    {'vid': 'transpower_165', 'name': '251_PS05_PB_520_REF_109967'},
    {'name': '31089', 'vid': 'transpower_064'}]

I have tried using sorted(viri_assets, key=lambda d: list(d.keys())) but it does not work.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
IDK
  • 99
  • 2
  • 9
  • If you are using python 3.6 or above the ordering is determined by insertion ordering. Rather than creating new dicts, which is really the only way to change the key order, you should fix where the dictionaries are created to either use `collections.OrderedDict` or if you are using 3.6 or later, just put the dictionaries in the right order to begin with. – toppk Sep 21 '22 at 17:55
  • @toppk Hopefully they're using at least Python 3.7 since all older versions are no longer supported – wjandrea Sep 21 '22 at 17:56
  • The reason I needed this done this way is because after this step I created a new dictionary based off the values of this list of dictionaries, so order is important. The API I am calling from outputs the data as a list of dicts, but out of order. – IDK Sep 21 '22 at 17:57
  • I gave two duplicates which answer the question. Sorting an individual dictionary by key works the same way as by value, you just make the corresponding change to the sort `key=`. Then it is a simple matter of applying that change to each element of the list. The reason the existing code does not work is that it means to sort *the list* according to *the overall* list of keys for the dicts, in their original order. – Karl Knechtel Sep 21 '22 at 18:01
  • Actually, when you sort the `.items()` of a given dictionary, the natural sort order will already be what you want: by key, then by value. – Karl Knechtel Sep 21 '22 at 18:03
  • @Karl I swapped out the duplicate to that effect – wjandrea Sep 21 '22 at 18:05
  • @wjandrea ah, nice find. As usual the site search is terrible. – Karl Knechtel Sep 21 '22 at 18:07

1 Answers1

3

You don't want to call sorted on your list, but on each dict of the list

Use .items() to get key-value pairs for each dict, and it'll sort them by the first element of the pair: the key. Set reverse to True to get "vid" before "name".

viri_assets = [{'vid': 'transpower_036', 'name': '221_02_PB_520_REF_174050'},
               {'vid': 'transpower_065', 'name': '222_05_KAL_T2E_YT_344991'},
               {'name': '226_02_INTL_PRSTR_ET_499802', 'vid': 'transpower_156'}]

viri_assets = [dict(sorted(d.items(), reverse=True)) for d in viri_assets]

print(viri_assets)

Output:

[{'vid': 'transpower_036', 'name': '221_02_PB_520_REF_174050'}, 
 {'vid': 'transpower_065', 'name': '222_05_KAL_T2E_YT_344991'}, 
 {'vid': 'transpower_156', 'name': '226_02_INTL_PRSTR_ET_499802'}]
wjandrea
  • 28,235
  • 9
  • 60
  • 81
azro
  • 53,056
  • 7
  • 34
  • 70