Sort multiple dictionaries identically, based on a specific order defined by a list
<p>I had a special case where multiple existing dictionaries had to be sorted based on the exact order of items in a list (not alphabetical). So for example the dictionaries were:</p>

<pre><code>dict_one = {"LastName": "Bar", "FirstName": "Foo", "Address": "Example Street 101", "Phone": "012345678"}
dict_two = {"Phone": "001122334455", "LastName": "Spammer", "FirstName": "Egg", "Address": "SSStreet 123"}
dict_three = {"Address": "Run Down Street 66", "Phone": "0987654321", "LastName": "Biker", "FirstName": "Random"}
</code></pre>

<p>And the list was:</p>

<pre><code>data_order = ["FirstName", "LastName", "Phone", "Address"]
</code></pre>

<p>With the expected result being the ability to create a file like this:</p>

<pre><code>FirstName;LastName;Phone;Address
Foo;Bar;012345678;Example Street 101
Egg;Spammer;001122334455;SSStreet 123
Random;Biker;0987654321;Run Down Street 66
</code></pre>

<p><strong>Note</strong>:
In my case, the real use was an Excel file using pyexcel-xls, but the CSV-like example above is probably closer to what is usually done, so the answers might be more universally applicable for CSV than Excel.</p>

<p>This is a classic use case for <a href="https://docs.python.org/3/library/csv.html#csv.DictWriter" rel="nofollow"><code>csv.DictWriter</code></a>, because your expected output is CSV-like (semi-colon delimiters instead of commas is supported) which would handle all of this for you, avoiding the need for ridiculous workaround involving <code>OrderedDict</code>, and making it easy to read the data back in without worrying about corner cases (<code>csv</code> automatically quotes fields if necessary, and parses quoted fields on read in as needed):</p>

<pre><code>with open('outputfile.txt', 'w', newline='') as f:
    csvout = csv.DictWriter(f, data_order, delimiter=';')

    # Write the header
    csvout.writeheader()
    csvout.writerow(dict_one)
    csvout.writerow(dict_two)
    csvout.writerow(dict_three)
</code></pre>

<p>That's it, <code>csv</code> handles ordering, (it knows the correct order from the <code>data_order</code> passed as <code>fieldnames</code> to the <code>DictWriter</code> constructor), formatting, etc.</p>

<hr>

<p>If you had some need to pull the values in a specific order from many <code>dict</code>s without writing them (since your use case doesn't even use the keys), <a href="https://docs.python.org/3/library/operator.html#operator.itemgetter" rel="nofollow"><code>operator.itemgetter</code></a> can be used to simplify this dramatically:</p>

<pre><code>from operator import itemgetter

getfields = itemgetter(*data_order)

dict_one_fields = getfields(dict_one)
</code></pre>

<p>which leaves <code>dict_one_fields</code> as a <code>tuple</code> with the requested fields in the requested order, <code>('Foo', 'Bar', '012345678', 'Example Street 101')</code>, and runs significantly faster than repeatedly indexing at the Python layer (<code>itemgetter</code> creates a C level "functor" that can retrieve all the requested values in a single call, with no Python level byte code at all for built-in keys like <code>str</code>).</p>

python python-3.x sorting