How do I sort a list of dictionaries by a value of the dictionary?

Questions : How do I sort a list of dictionaries by a value of the dictionary?

How do I sort a list of dictionaries by a specific key’s value? Given:

[{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}] 

When sorted by name, it should become:

[{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] 

Total Answers: 19 Answers 19


Popular Answers:

  1. The sorted() function takes a key= parameter

    newlist = sorted(list_to_be_sorted, key=lambda d: d['name']) 

    Alternatively, you can use operator.itemgetter instead of defining the function yourself

    from operator import itemgetter newlist = sorted(list_to_be_sorted, key=itemgetter('name')) 

    For completeness, add reverse=True to sort in descending order

    newlist = sorted(list_to_be_sorted, key=itemgetter('name'), reverse=True) 
  2. my_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] my_list.sort(lambda x,y : cmp(x['name'], y['name'])) 

    my_list will now be what you want.

    Or better:

    Since Python 2.4, there’s a key argument is both more efficient and neater:

    my_list = sorted(my_list, key=lambda k: k['name']) 

    …the lambda is, IMO, easier to understand than operator.itemgetter, but your mileage may vary.

  3. a = [{'name':'Homer', 'age':39}, ...] # This changes the list a a.sort(key=lambda k : k['name']) # This returns a new list (a is not modified) sorted(a, key=lambda k : k['name']) 
  4. import operator a_list_of_dicts.sort(key=operator.itemgetter('name')) 

    ‘key’ is used to sort by an arbitrary value and ‘itemgetter’ sets that value to each item’s ‘name’ attribute.

  5. I guess you’ve meant:

    [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] 

    This would be sorted like this:

    sorted(l,cmp=lambda x,y: cmp(x['name'],y['name'])) 
  6. You could use a custom comparison function, or you could pass in a function that calculates a custom sort key. That’s usually more efficient as the key is only calculated once per item, while the comparison function would be called many more times.

    You could do it this way:

    def mykey(adict): return adict['name'] x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}] sorted(x, key=mykey) 

    But the standard library contains a generic routine for getting items of arbitrary objects: itemgetter. So try this instead:

    from operator import itemgetter x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}] sorted(x, key=itemgetter('name')) 
  7. Using the Schwartzian transform from Perl,

    py = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] 

    do

    sort_on = "name" decorated = [(dict_[sort_on], dict_) for dict_ in py] decorated.sort() result = [dict_ for (key, dict_) in decorated] 

    gives

    >>> result [{'age': 10, 'name': 'Bart'}, {'age': 39, 'name': 'Homer'}] 

    More on the Perl Schwartzian transform:

    In computer science, the Schwartzian transform is a Perl programming idiom used to improve the efficiency of sorting a list of items. This idiom is appropriate for comparison-based sorting when the ordering is actually based on the ordering of a certain property (the key) of the elements, where computing that property is an intensive operation that should be performed a minimal number of times. The Schwartzian Transform is notable in that it does not use named temporary arrays.

  8. You have to implement your own comparison function that will compare the dictionaries by values of name keys. See Sorting Mini-HOW TO from PythonInfo Wiki

  9. Sometimes we need to use lower(). For example,

    lists = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'abby', 'age':9}] lists = sorted(lists, key=lambda k: k['name']) print(lists) # [{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}, {'name':'abby', 'age':9}] lists = sorted(lists, key=lambda k: k['name'].lower()) print(lists) # [ {'name':'abby', 'age':9}, {'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}] 
  10. Using the Pandas package is another method, though its runtime at large scale is much slower than the more traditional methods proposed by others:

    import pandas as pd listOfDicts = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}] df = pd.DataFrame(listOfDicts) df = df.sort_values('name') sorted_listOfDicts = df.T.to_dict().values() 

    Here are some benchmark values for a tiny list and a large (100k+) list of dicts:

    setup_large = "listOfDicts = []; [listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10})) for _ in range(50000)]; from operator import itemgetter;import pandas as pd; df = pd.DataFrame(listOfDicts);" setup_small = "listOfDicts = []; listOfDicts.extend(({'name':'Homer', 'age':39}, {'name':'Bart', 'age':10})); from operator import itemgetter;import pandas as pd; df = pd.DataFrame(listOfDicts);" method1 = "newlist = sorted(listOfDicts, key=lambda k: k['name'])" method2 = "newlist = sorted(listOfDicts, key=itemgetter('name')) " method3 = "df = df.sort_values('name'); sorted_listOfDicts = df.T.to_dict().values()" import timeit t = timeit.Timer(method1, setup_small) print('Small Method LC: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup_small) print('Small Method LC2: ' + str(t.timeit(100))) t = timeit.Timer(method3, setup_small) print('Small Method Pandas: ' + str(t.timeit(100))) t = timeit.Timer(method1, setup_large) print('Large Method LC: ' + str(t.timeit(100))) t = timeit.Timer(method2, setup_large) print('Large Method LC2: ' + str(t.timeit(100))) t = timeit.Timer(method3, setup_large) print('Large Method Pandas: ' + str(t.timeit(1))) #Small Method LC: 0.000163078308105 #Small Method LC2: 0.000134944915771 #Small Method Pandas: 0.0712950229645 #Large Method LC: 0.0321750640869 #Large Method LC2: 0.0206089019775 #Large Method Pandas: 5.81405615807 
  11. Here is the alternative general solution – it sorts elements of a dict by keys and values.

    The advantage of it – no need to specify keys, and it would still work if some keys are missing in some of dictionaries.

    def sort_key_func(item): """ Helper function used to sort list of dicts :param item: dict :return: sorted list of tuples (k, v) """ pairs = [] for k, v in item.items(): pairs.append((k, v)) return sorted(pairs) sorted(A, key=sort_key_func) 
  12. If you do not need the original list of dictionaries, you could modify it in-place with sort() method using a custom key function.

    Key function:

    def get_name(d): """ Return the value of a key in a dictionary. """ return d["name"] 

    The list to be sorted:

    data_one = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}] 

    Sorting it in-place:

    data_one.sort(key=get_name) 

    If you need the original list, call the sorted() function passing it the list and the key function, then assign the returned sorted list to a new variable:

    data_two = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age': 10}] new_data = sorted(data_two, key=get_name) 

    Printing data_one and new_data.

    >>> print(data_one) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] >>> print(new_data) [{'name': 'Bart', 'age': 10}, {'name': 'Homer', 'age': 39}] 
  13. Let’s say I have a dictionary D with the elements below. To sort, just use the key argument in sorted to pass a custom function as below:

    D = {'eggs': 3, 'ham': 1, 'spam': 2} def get_count(tuple): return tuple[1] sorted(D.items(), key = get_count, reverse=True) # Or sorted(D.items(), key = lambda x: x[1], reverse=True) # Avoiding get_count function call 

    Check this out.

  14. I have been a big fan of a filter with lambda. However, it is not best option if you consider time complexity.

    First option

    sorted_list = sorted(list_to_sort, key= lambda x: x['name']) # Returns list of values 

    Second option

    list_to_sort.sort(key=operator.itemgetter('name')) # Edits the list, and does not return a new list 

    Fast comparison of execution times

    # First option python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" "sorted_l = sorted(list_to_sort, key=lambda e: e['name'])" 

    1000000 loops, best of 3: 0.736 µsec per loop

    # Second option python3.6 -m timeit -s "list_to_sort = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}, {'name':'Faaa', 'age':57}, {'name':'Errr', 'age':20}]" -s "sorted_l=[]" -s "import operator" "list_to_sort.sort(key=operator.itemgetter('name'))" 

    1000000 loops, best of 3: 0.438 µsec per loop

  15. If performance is a concern, I would use operator.itemgetter instead of lambda as built-in functions perform faster than hand-crafted functions. The itemgetter function seems to perform approximately 20% faster than lambda based on my testing.

    From https://wiki.python.org/moin/PythonSpeed:

    Likewise, the builtin functions run faster than hand-built equivalents. For example, map(operator.add, v1, v2) is faster than map(lambda x,y: x+y, v1, v2).

    Here is a comparison of sorting speed using lambda vs itemgetter.

    import random import operator # Create a list of 100 dicts with random 8-letter names and random ages from 0 to 100. l = [{'name': ''.join(random.choices(string.ascii_lowercase, k=8)), 'age': random.randint(0, 100)} for i in range(100)] # Test the performance with a lambda function sorting on name %timeit sorted(l, key=lambda x: x['name']) 13 µs ± 388 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) # Test the performance with itemgetter sorting on name %timeit sorted(l, key=operator.itemgetter('name')) 10.7 µs ± 38.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) # Check that each technique produces the same sort order sorted(l, key=lambda x: x['name']) == sorted(l, key=operator.itemgetter('name')) True 

    Both techniques sort the list in the same order (verified by execution of the final statement in the code block), but the first one is a little faster.

  16. list_to_be_sorted = [ {'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
  17. sorting by multiple columns, while in descending order on some of them: the cmps array is global to the cmp function, containing field names and inv == -1 for desc 1 for asc

    def cmpfun(a, b): for (name, inv) in cmps: res = cmp(a[name], b[name]) if res != 0: return res * inv return 0 data = [ dict(name='alice', age=10), dict(name='baruch', age=9), dict(name='alice', age=11), ] all_cmps = [ [('name', 1), ('age', -1)], [('name', 1), ('age', 1)], [('name', -1), ('age', 1)],] print 'data:', data for cmps in all_cmps: print 'sort:', cmps; print sorted(data, cmpfun) 
  18. Most professional programmers suck

    I have come across too many people doing this job for their living who were plain crappy at what they were doing. Crappy code, bad communication skills, no interest in new technology whatsoever. Too many, too many…

  19. A degree in computer science does not—and is not supposed to—teach you to be a programmer.

    Programming is a trade, computer science is a field of study. You can be a great programmer and a poor computer scientist and a great computer scientist and an awful programmer. It is important to understand the difference.

    If you want to be a programmer, learn Java. If you want to be a computer scientist, learn at least three almost completely different languages. e.g. (assembler, c, lisp, ruby, smalltalk)

  20. SESE (Single Entry Single Exit) is not law

    Example:

    public int foo() { if( someCondition ) { return 0; } return -1; } 

    vs:

    public int foo() { int returnValue = -1; if( someCondition ) { returnValue = 0; } return returnValue; } 

    My team and I have found that abiding by this all the time is actually counter-productive in many cases.

  21. C++ is one of the WORST programming languages – EVER.

    It has all of the hallmarks of something designed by committee – it does not do any given job well, and does some jobs (like OO) terribly. It has a “kitchen sink” desperation to it that just won’t go away.

    It is a horrible “first language” to learn to program with. You get no elegance, no assistance (from the language). Instead you have bear traps and mine fields (memory management, templates, etc.).

    It is not a good language to try to learn OO concepts. It behaves as “C with a class wrapper” instead of a proper OO language.

    I could go on, but will leave it at that for now. I have never liked programming in C++, and although I “cut my teeth” on FORTRAN, I totally loved programming in C. I still think C was one of the great “classic” languages. Something that C++ is certainly NOT, in my opinion.

    Cheers,

    -R

    EDIT: To respond to the comments on teaching C++. You can teach C++ in two ways – either teaching it as C “on steroids” (start with variables, conditions, loops, etc), or teaching it as a pure “OO” language (start with classes, methods, etc). You can find teaching texts that use one or other of these approaches. I prefer the latter approach (OO first) as it does emphasize the capabilities of C++ as an OO language (which was the original design emphasis of C++). If you want to teach C++ “as C”, then I think you should teach C, not C++.

    But the problem with C++ as a first language in my experience is that the language is simply too BIG to teach in one semester, plus most “intro” texts try and cover everything. It is simply not possible to cover all the topics in a “first language” course. You have to at least split it into 2 semesters, and then it’s no longer “first language”, IMO.

    I do teach C++, but only as a “new language” – that is, you must be proficient in some prior “pure” language (not scripting or macros) before you can enroll in the course. C++ is a very fine “second language” to learn, IMO.

    -R

    ‘Nother Edit: (to Konrad)

    I do not at all agree that C++ “is superior in every way” to C. I spent years coding C programs for microcontrollers and other embedded applications. The C compilers for these devices are highly optimized, often producing code as good as hand-coded assembler. When you move to C++, you gain a tremendous overhead imposed by the compiler in order to manage language features you may not use. In embedded applications, you gain little by adding classes and such, IMO. What you need is tight, clean code. You can write it in C++, but then you’re really just writing C, and the C compilers are more optimized in these applications.

    I wrote a MIDI engine, first in C, later in C++ (at the vendor’s request) for an embedded controller (sound card). In the end, to meet the performance requirements (MIDI timings, etc) we had to revert to pure C for all of the core code. We were able to use C++ for the high-level code, and having classes was very sweet – but we needed C to get the performance at the lower level. The C code was an order of magnitude faster than the C++ code, but hand coded assembler was only slightly faster than the compiled C code. This was back in the early 1990s, just to place the events properly.

    -R

  22. A degree in Computer Science or other IT area DOES make you a more well rounded programmer

    I don’t care how many years of experience you have, how many blogs you’ve read, how many open source projects you’re involved in. A qualification (I’d recommend longer than 3 years) exposes you to a different way of thinking and gives you a great foundation.

    Just because you’ve written some better code than a guy with a BSc in Computer Science, does not mean you are better than him. What you have he can pick up in an instant which is not the case the other way around.

    Having a qualification shows your commitment, the fact that you would go above and beyond experience to make you a better developer. Developers which are good at what they do AND have a qualification can be very intimidating.

    I would not be surprized if this answer gets voted down.

    Also, once you have a qualification, you slowly stop comparing yourself to those with qualifications (my experience). You realize that it all doesn’t matter at the end, as long as you can work well together.

    Always act mercifully towards other developers, irrespective of qualifications.

  23. Lazy Programmers are the Best Programmers

    A lazy programmer most often finds ways to decrease the amount of time spent writing code (especially a lot of similar or repeating code). This often translates into tools and workflows that other developers in the company/team can benefit from.

    As the developer encounters similar projects he may create tools to bootstrap the development process (e.g. creating a DRM layer that works with the company’s database design paradigms).

    Furthermore, developers such as these often use some form of code generation. This means all bugs of the same type (for example, the code generator did not check for null parameters on all methods) can often be fixed by fixing the generator and not the 50+ instances of that bug.

    A lazy programmer may take a few more hours to get the first product out the door, but will save you months down the line.

  24. Don’t use inheritance unless you can explain why you need it.

  25. The world needs more GOTOs

    GOTOs are avoided religiously often with no reasoning beyond “my professor told me GOTOs are bad.” They have a purpose and would greatly simplify production code in many places.

    That said, they aren’t really necessary in 99% of the code you’ll ever write.

  26. I’ve been burned for broadcasting these opinions in public before, but here goes:

    Well-written code in dynamically typed languages follows static-typing conventions

    Having used Python, PHP, Perl, and a few other dynamically typed languages, I find that well-written code in these languages follows static typing conventions, for example:

    • Its considered bad style to re-use a variable with different types (for example, its bad style to take a list variable and assign an int, then assign the variable a bool in the same method). Well-written code in dynamically typed languages doesn’t mix types.

    • A type-error in a statically typed language is still a type-error in a dynamically typed language.

    • Functions are generally designed to operate on a single datatype at a time, so that a function which accepts a parameter of type T can only sensibly be used with objects of type T or subclasses of T.

    • Functions designed to operator on many different datatypes are written in a way that constrains parameters to a well-defined interface. In general terms, if two objects of types A and B perform a similar function, but aren’t subclasses of one another, then they almost certainly implement the same interface.

    While dynamically typed languages certainly provide more than one way to crack a nut, most well-written, idiomatic code in these languages pays close attention to types just as rigorously as code written in statically typed languages.

    Dynamic typing does not reduce the amount of code programmers need to write

    When I point out how peculiar it is that so many static-typing conventions cross over into dynamic typing world, I usually add “so why use dynamically typed languages to begin with?”. The immediate response is something along the lines of being able to write more terse, expressive code, because dynamic typing allows programmers to omit type annotations and explicitly defined interfaces. However, I think the most popular statically typed languages, such as C#, Java, and Delphi, are bulky by design, not as a result of their type systems.

    I like to use languages with a real type system like OCaml, which is not only statically typed, but its type inference and structural typing allow programmers to omit most type annotations and interface definitions.

    The existence of the ML family of languages demostrates that we can enjoy the benefits of static typing with all the brevity of writing in a dynamically typed language. I actually use OCaml’s REPL for ad hoc, throwaway scripts in exactly the same way everyone else uses Perl or Python as a scripting language.

  27. Programmers who spend all day answering questions on Stackoverflow are probably not doing the work they are being paid to do.

  28. Code layout does matter

    Maybe specifics of brace position should remain purely religious arguments – but it doesn’t mean that all layout styles are equal, or that there are no objective factors at all!

    The trouble is that the uber-rule for layout, namely: “be consistent”, sound as it is, is used as a crutch by many to never try to see if their default style can be improved on – and that, furthermore, it doesn’t even matter.

    A few years ago I was studying Speed Reading techniques, and some of the things I learned about how the eye takes in information in “fixations”, can most optimally scan pages, and the role of subconsciously picking up context, got me thinking about how this applied to code – and writing code with it in mind especially.

    It led me to a style that tended to be columnar in nature, with identifiers logically grouped and aligned where possible (in particular I became strict about having each method argument on its own line). However, rather than long columns of unchanging structure it’s actually beneficial to vary the structure in blocks so that you end up with rectangular islands that the eye can take in in a single fixture – even if you don’t consciously read every character.

    The net result is that, once you get used to it (which typically takes 1-3 days) it becomes pleasing to the eye, easier and faster to comprehend, and is less taxing on the eyes and brain because it’s laid out in a way that makes it easier to take in.

    Almost without exception, everyone I have asked to try this style (including myself) initially said, “ugh I hate it!”, but after a day or two said, “I love it – I’m finding it hard not to go back and rewrite all my old stuff this way!”.

    I’ve been hoping to find the time to do more controlled experiments to collect together enough evidence to write a paper on, but as ever have been too busy with other things. However this seemed like a good opportunity to mention it to people interested in controversial techniques 🙂

    [Edit]

    I finally got around to blogging about this (after many years parked in the “meaning to” phase): Part one, Part two, Part three.

  29. Opinion: explicit variable declaration is a great thing.

    I’ll never understand the “wisdom” of letting the developer waste costly time tracking down runtime errors caused by variable name typos instead of simply letting the compiler/interpreter catch them.

    Nobody’s ever given me an explanation better than “well it saves time since I don’t have to write ‘int i;’.” Uhhhhh… yeah, sure, but how much time does it take to track down a runtime error?

  30. Opinion: Never ever have different code between “debug” and “release” builds

    The main reason being that release code almost never gets tested. Better to have the same code running in test as it is in the wild.

  31. Pagination is never what the user wants

    If you start having the discussion about where to do pagination, in the database, in the business logic, on the client, etc. then you are asking the wrong question. If your app is giving back more data than the user needs, figure out a way for the user to narrow down what they need based on real criteria, not arbitrary sized chunks. And if the user really does want all those results, then give them all the results. Who are you helping by giving back 20 at a time? The server? Is that more important than your user?

    [EDIT: clarification, based on comments]

    As a real world example, let’s look at this Stack Overflow question. Let’s say I have a controversial programming opinion. Before I post, I’d like to see if there is already an answer that addresses the same opinion, so I can upvote it. The only option I have is to click through every page of answers.

    I would prefer one of these options:

    1. Allow me to search through the answers (a way for me to narrow down what I need based on real criteria).

    2. Allow me to see all the answers so I can use my browser’s “find” option (give me all the results).

    The same applies if I just want to find an answer I previously read, but can’t find anymore. I don’t know when it was posted or how many votes it has, so the sorting options don’t help. And even if I did, I still have to play a guessing game to find the right page of results. The fact that the answers are paginated and I can directly click into one of a dozen pages is no help at all.


    bmb

  32. Respect the Single Responsibility Principle

    At first glance you might not think this would be controversial, but in my experience when I mention to another developer that they shouldn’t be doing everything in the page load method they often push back … so for the children please quit building the “do everything” method we see all to often.

Tasg: python, list

Answer Link
jidam
  • Unable to run NoraUI mvn verify goal
  • Unable to run my app on emulator in VS Code
  • Unable to run multiple instances of libVLC(MobileVLCKit) in IOS via flutter framework
  • Unable to run make on griddb source on ubuntu 20.04 (building from source)
  • Unable to run latexindent macOS Monterey 12.0.1
  • Unable to run kotlinc-native command
  • Unable to run JUnit Test… Java.lang.ExceptionInInitializerError (Android Studio)
  • Unable to run java with -Xmx > 966m
  • Unable to run ionic cap run android from wsl2 inorder to start android emulator
  • Unable to run Intel HAXM installer: Cannot start process, the working directory does not exist
  • fs
  • Unable to run Google Analytics sample code
  • unable to run flutter run after upgarding to flutter 2.8.0 from 2.5.3
  • Unable to run Django with PostgreSQL in Docker
  • Unable to Run Container Using testcontainers
  • Unable to run ClojureScript Hello World program, Error building classpath. Error reading edn.
  • unable to run client command for apache karaf 4.3.3 through remote server
  • Unable to run c program 2nd time using eclipse
  • unable to run c++ in visual studio code on m1 chipset
  • Unable to run Android Instrumented Tests
  • Unable to run adb, check your Android SDK installation and ANDROID_SDK_ROOT environment variable: …AndroidSdkplatform-toolsadb.exe
  • Unable to run a singlespecific .spec.ts file through angular cli using ng test –include option
  • Unable to run a Mango query
  • Unable to return response back to view in laravel from package
  • Unable to return object reference in std::optional
  • Unable to return NULL in a function that expects an integer return type
  • Unable to return correct change in JavaScript Cash Register
  • Unable to retrieve version information from Elasticsearch nodes. Request timed out
  • Unable to retrieve values from Axios Response data
  • Unable to retrieve dotenv JWT secret Error: secretOrPrivateKey must have a value
  • Unable to resolve your shell environment
  • Unable to resolve token for FCM while implementing Push notification for Xamarin
  • Unable to resolve the request yii
  • Unable to resolve service for type Swashbuckle.AspNetCore.Swagger.ISwaggerProvider
  • Unable to resolve service for type Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger