Re: Sort list of dictionaries by key (case insensitive)

Discussion in 'Python' started by Nico Grubert, Jan 13, 2010.

  1. Nico Grubert

    Nico Grubert Guest

    Thanks a lot Stefan & Peter.

    I'm almost there (except sorting of umlauts does not work yet).


    import locale

    def sorted(items, key):
    decorated = [(key(item), index, item) for index, item in
    enumerate(items)]
    decorated.sort()
    return [item[2] for item in decorated]

    items = [{'title':'the Ähnlich', 'id':1},
    {'title':'The Storm', 'id':2},
    {'title':'the bible','id':3},
    {'title':'The thunder', 'id':4}]

    print sorted(items, key=lambda d: locale.strxfrm(d.get('title')))

    -> [{'id': 2, 'title': 'The Storm'}, {'id': 4, 'title': 'The thunder'},
    {'id': 3, 'title': 'the bible'}, {'id': 1, 'title': 'the \xc4hnlich'}]


    The entry with the umlaut is the last item in but according to german
    umlaut rules it should be the first item in the result.
    Do I have to set anything with the locale module?


    Regards
    Nico
    Nico Grubert, Jan 13, 2010
    #1
    1. Advertising

  2. Nico Grubert, 13.01.2010 16:18:
    > print sorted(items, key=lambda d: locale.strxfrm(d.get('title')))
    >
    > -> [{'id': 2, 'title': 'The Storm'}, {'id': 4, 'title': 'The thunder'},
    > {'id': 3, 'title': 'the bible'}, {'id': 1, 'title': 'the \xc4hnlich'}]
    >
    > The entry with the umlaut is the last item in but according to german
    > umlaut rules it should be the first item in the result.
    > Do I have to set anything with the locale module?


    http://wiki.python.org/moin/HowTo/Sorting#Topicstobecovered

    Stefan
    Stefan Behnel, Jan 13, 2010
    #2
    1. Advertising

  3. Nico Grubert

    Peter Otten Guest

    Nico Grubert wrote:

    > Thanks a lot Stefan & Peter.
    >
    > I'm almost there (except sorting of umlauts does not work yet).
    >
    >
    > import locale


    locale.setlocale(locale.LC_ALL, "")

    > def sorted(items, key):
    > decorated = [(key(item), index, item) for index, item in
    > enumerate(items)]
    > decorated.sort()
    > return [item[2] for item in decorated]
    >
    > items = [{'title':'the Ähnlich', 'id':1},
    > {'title':'The Storm', 'id':2},
    > {'title':'the bible','id':3},
    > {'title':'The thunder', 'id':4}]
    >
    > print sorted(items, key=lambda d: locale.strxfrm(d.get('title')))
    >
    > -> [{'id': 2, 'title': 'The Storm'}, {'id': 4, 'title': 'The thunder'},
    > {'id': 3, 'title': 'the bible'}, {'id': 1, 'title': 'the \xc4hnlich'}]
    >
    >
    > The entry with the umlaut is the last item in but according to german
    > umlaut rules it should be the first item in the result.
    > Do I have to set anything with the locale module?


    Adding the setlocale() call will suffice provided your script uses the same
    encoding as your environment. If not something like

    # -*- coding:utf-8 -*-
    import locale

    locale.setlocale(locale.LC_ALL, "")
    encoding = locale.getlocale()[1]

    def sorted(items, key):
    decorated = [(key(item), index, item) for index, item in
    enumerate(items)]
    decorated.sort()
    return [item[2] for item in decorated]

    # book titles use unicode
    items = [{'title':u'the Ähnlich', 'id':1},
    {'title':u'The Storm', 'id':2},
    {'title':u'the bible','id':3},
    {'title':u'The thunder', 'id':4}]

    def sortkey(item):
    s = item["title"].encode(encoding)
    return locale.strxfrm(s)

    print sorted(items, key=sortkey)

    may be a bit more robust. If your source code doesn't use UTF-8 you have to
    modify the coding declaration at the top accordingly.

    Peter
    Peter Otten, Jan 13, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tee
    Replies:
    3
    Views:
    7,802
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  2. Replies:
    1
    Views:
    2,478
    Mark P
    Apr 6, 2007
  3. Nico Grubert
    Replies:
    2
    Views:
    338
    Florian Diesch
    Jan 13, 2010
  4. Nico Grubert
    Replies:
    2
    Views:
    330
    Stefan Behnel
    Jan 13, 2010
  5. san
    Replies:
    2
    Views:
    215
    Prasad, Ramit
    Nov 27, 2012
Loading...

Share This Page