Re: Sort list of dictionaries
Charles Heizer wrote: Hello, I'm new to python and I'm trying to find the right way to solve this issue I have. I'm trying to sort this list by name and then by version numbers. The problem I'm having is that I can not get the version numbers sorted with the highest at the top or sorted properly. mylist = [{'name': u'com.google.earth', 'version': u'7.1.2.2041'}, {'name': u'com.google.earth', 'version': u'7.1.2.2019'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.93'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.91'}, [...] ] sortedlist = sorted(mylist , key=lambda x, y: x['name'] LooseVersion(elem['version'])), reverse=True) There's a syntax error there. Is there supposed to be a comma between the x['name'] and the LooseVersion function call? Once you've fixed the syntax error, you can then fix the mysterious elem, and the fact that your key function takes too many arguments. The key function should take *one* argument, which in your case is a dict. So: def sort_by_version(d): name = d['name'] version = d['version'] return (name, [int(substr) for substr in version.split('.')]) sortedlist = sorted(mylist, key=sort_by_version) should get you started. It may not quiet do what you want, but you can adjust the sort_by_version function as needed. -- Steve -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Wed, Mar 4, 2015 at 2:56 AM, Charles Heizer ceh...@gmail.com wrote: Personally, I prefer to not use a lambda: def name_version(elem): return elem['name'], LooseVersion(elem['version']) result = sorted(mylist, key=name_version, reverse=True) Peter, thank you. Me being new to Python why don't you prefer to use a lambda? Using lambda is fine if it's really clear what's going on (usually, if it's an extremely simple function), but if your expression goes across multiple lines because of the function parameter, it's usually simpler to break the function out into a separate def statement and then use that. There's ultimately no difference[1] between a lambda function and a def function, apart from the fact that a function created with lambda always has the name lambda. ChrisA [1] Modulo bugs, eg a weird edge case with lambda and yield; certainly no intentional difference. -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Monday, March 2, 2015 at 11:23:37 AM UTC-8, Peter Otten wrote: Charles Heizer wrote: Never mind, the light bulb finally went off. :-\ sortedlist = sorted(mylist , key=lambda elem: %s %s % ( elem['name'], (..join([i.zfill(5) for i in elem['version'].split(.)])) ), reverse=True) This lightbulb will break with version numbers 9 ;) Here are two alternatives: result = sorted( mylist, key=lambda elem: (elem['name'], LooseVersion(elem['version'])), reverse=True) result = sorted( mylist, key=lambda e: (e[name], tuple(map(int, e[version].split(., reverse=True) Personally, I prefer to not use a lambda: def name_version(elem): return elem['name'], LooseVersion(elem['version']) result = sorted(mylist, key=name_version, reverse=True) Peter, thank you. Me being new to Python why don't you prefer to use a lambda? -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Tuesday, 3 March 2015 16:09:31 UTC, Chris Angelico wrote: On Wed, Mar 4, 2015 at 2:56 AM, Charles Heizer wrote: Personally, I prefer to not use a lambda: def name_version(elem): return elem['name'], LooseVersion(elem['version']) result = sorted(mylist, key=name_version, reverse=True) Peter, thank you. Me being new to Python why don't you prefer to use a lambda? Using lambda is fine if it's really clear what's going on (usually, if it's an extremely simple function), but if your expression goes across multiple lines because of the function parameter, it's usually simpler to break the function out into a separate def statement and then use that. There's ultimately no difference[1] between a lambda function and a def function, apart from the fact that a function created with lambda always has the name lambda. ChrisA [1] Modulo bugs, eg a weird edge case with lambda and yield; certainly no intentional difference. The main point is that a def gives your function a name, whereas lambda is unnamed. It sometimes feels harder to have to think of a name for something that seems simple, like your key function. But when you come back to it in a few months, the name is incredibly useful documentation as to what's going on. Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
Charles Heizer wrote: On Monday, March 2, 2015 at 11:23:37 AM UTC-8, Peter Otten wrote: Charles Heizer wrote: Never mind, the light bulb finally went off. :-\ sortedlist = sorted(mylist , key=lambda elem: %s %s % ( elem['name'], (..join([i.zfill(5) for i in elem['version'].split(.)])) ), reverse=True) This lightbulb will break with version numbers 9 ;) Here are two alternatives: result = sorted( mylist, key=lambda elem: (elem['name'], LooseVersion(elem['version'])), reverse=True) result = sorted( mylist, key=lambda e: (e[name], tuple(map(int, e[version].split(., reverse=True) Personally, I prefer to not use a lambda: def name_version(elem): return elem['name'], LooseVersion(elem['version']) result = sorted(mylist, key=name_version, reverse=True) Peter, thank you. Me being new to Python why don't you prefer to use a lambda? I find def name_version(elem): return elem['name'], LooseVersion(elem['version']) more readable than lambda elem: (elem['name'], LooseVersion(elem['version'])) and I can understand what result = sorted(mylist, key=name_version, reverse=True) is supposed to do without grokking the implementation of name_version() first. I can spot a potential bug -- are the names really supposed to occur in reverse order, not just the versions? -- again without a look at the implementation. If I intend to use the script more than once or if I want to rely on the result I can write unit tests for name_version() to increase confidence that it does what I expect. Finally I can add a docstring to make it more discoverable in the interactive interpreter. -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Tue, Mar 3, 2015 at 12:07 AM, Chris Angelico ros...@gmail.com wrote: Heh, I think that mght be a bit abusive :) I'm not sure that you want to depend on the version numbers fitting inside the rules for IP addresses, especially given that the example has a component of 2214. Indeed, I was mistaken ipaddress.ip_address(1000.1.2.3) Traceback (most recent call last): File stdin, line 1, in module File /opt/python/lib/python3.4/ipaddress.py, line 54, in ip_address address) ValueError: '1000.1.2.3' does not appear to be an IPv4 or IPv6 address I was overcome by how neat I think the ipaddress module is. I have not used it yet, but I expect someday I will, and I appreciate how Python makes my job easier by doing much of my work for me. A colleague yesterday asked how I guaranteed my temporary file names would not collide with another file, and my answer was I don't have to worry about it, someone else figured it out with the tempfile module. -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Wed, Mar 4, 2015 at 1:45 AM, Jason Friedman jsf80...@gmail.com wrote: I appreciate how Python makes my job easier by doing much of my work for me. A colleague yesterday asked how I guaranteed my temporary file names would not collide with another file, and my answer was I don't have to worry about it, someone else figured it out with the tempfile module. Though in that case, Python isn't actually the one doing most of the work - the tempfile module handballs responsibility to the lower-level functions. But yes, there's HEAPS that you don't have to worry about, because it's Someone Else's Problem. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Because it's a string they're sorted lexicographically, and in that ordering 40.0.2214.111 is less than 40.0.2214.91. Instead of a string you should probably use some sort of version info tuple. A simple tuple of ints may suffice, although you may need to get a little cleverer if there are ever any version strings that aren't entirely dotted numeric. Also, Python 3.4 comes with an ipaddress module. import ipaddress address_string_1 = 2.2.3.4 address_string_2 = 10.2.3.4 address_string_2 address_string_1 False ip_address_1 = ipaddress.ip_address(address_string_1) ip_address_2 = ipaddress.ip_address(address_string_2) ip_address_2 ip_address_1 True -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Tue, Mar 3, 2015 at 4:33 PM, Jason Friedman jsf80...@gmail.com wrote: This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Because it's a string they're sorted lexicographically, and in that ordering 40.0.2214.111 is less than 40.0.2214.91. Instead of a string you should probably use some sort of version info tuple. A simple tuple of ints may suffice, although you may need to get a little cleverer if there are ever any version strings that aren't entirely dotted numeric. Also, Python 3.4 comes with an ipaddress module. Heh, I think that mght be a bit abusive :) I'm not sure that you want to depend on the version numbers fitting inside the rules for IP addresses, especially given that the example has a component of 2214. The right way to compare version numbers is usually to split them on dots, then treat each part as a separate number. I say usually because there are complications like alpha, RC, -git, +deb7u1, and so on, but if the entire version number consists of digits and dots, then tuple(int(x) for x in version_number.split(.)) will give you a properly-sortable key. BTW, Jason: It's usually courteous to acknowledge who you're quoting. If you look at the top of my post here, you'll see that there's a line saying your name and email address, and the date/time that you made your post; but underneath that is just straight text, because your post didn't extend the same courtesy to the previous posters. When you trim quoted text, do please try to keep at least the first acknowledgement line - the one showing who you're actually quoting. Whether or not you keep additional headers is up to you (sometimes it's easy, but other times it's fiddly), but the first one is your responsibility. Thanks! ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
Sorry, sortedlist = sorted(mylist , key=lambda elem: %s %s % (elem['name'], LooseVersion(elem['version'])), reverse=True) This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Thanks, Charlie On Monday, March 2, 2015 at 10:32:40 AM UTC-8, Emile van Sebille wrote: On 3/2/2015 10:17 AM, Charles Heizer wrote: Hello, I'm new to python and I'm trying to find the right way to solve this issue I have. I'm trying to sort this list by name and then by version numbers. The problem I'm having is that I can not get the version numbers sorted with the highest at the top or sorted properly. mylist = [{'name': u'com.google.earth', 'version': u'7.1.2.2041'}, {'name': u'com.google.earth', 'version': u'7.1.2.2019'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.93'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.91'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.111'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.99'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.95'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.71'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.122'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.111'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.104'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.101'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.94'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.120'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.143'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.125'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.153'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.114'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.137'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.131'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.116'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.152'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.149'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.146'}, {'name': u'com.google.Chrome', 'version': u'32.0.1700.107'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.63'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.57'}] sortedlist = sorted(mylist , key=lambda x, y: x['name'] LooseVersion(elem['version'])), reverse=True) You'll need to fix LooseVersion or elem or both -- or show them so we can help. Emile Thanks, Charlie -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On 3/2/2015 10:17 AM, Charles Heizer wrote: Hello, I'm new to python and I'm trying to find the right way to solve this issue I have. I'm trying to sort this list by name and then by version numbers. The problem I'm having is that I can not get the version numbers sorted with the highest at the top or sorted properly. mylist = [{'name': u'com.google.earth', 'version': u'7.1.2.2041'}, {'name': u'com.google.earth', 'version': u'7.1.2.2019'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.93'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.91'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.111'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.99'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.95'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.71'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.122'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.111'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.104'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.101'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.94'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.120'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.143'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.125'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.153'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.114'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.137'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.131'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.116'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.152'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.149'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.146'}, {'name': u'com.google.Chrome', 'version': u'32.0.1700.107'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.63'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.57'}] sortedlist = sorted(mylist , key=lambda x, y: x['name'] LooseVersion(elem['version'])), reverse=True) You'll need to fix LooseVersion or elem or both -- or show them so we can help. Emile Thanks, Charlie -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
Charles Heizer wrote: Never mind, the light bulb finally went off. :-\ sortedlist = sorted(mylist , key=lambda elem: %s %s % ( elem['name'], (..join([i.zfill(5) for i in elem['version'].split(.)])) ), reverse=True) This lightbulb will break with version numbers 9 ;) Here are two alternatives: result = sorted( mylist, key=lambda elem: (elem['name'], LooseVersion(elem['version'])), reverse=True) result = sorted( mylist, key=lambda e: (e[name], tuple(map(int, e[version].split(., reverse=True) Personally, I prefer to not use a lambda: def name_version(elem): return elem['name'], LooseVersion(elem['version']) result = sorted(mylist, key=name_version, reverse=True) -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On Mon, Mar 2, 2015 at 11:38 AM, Charles Heizer ceh...@gmail.com wrote: Sorry, sortedlist = sorted(mylist , key=lambda elem: %s %s % (elem['name'], LooseVersion(elem['version'])), reverse=True) This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Because it's a string they're sorted lexicographically, and in that ordering 40.0.2214.111 is less than 40.0.2214.91. Instead of a string you should probably use some sort of version info tuple. A simple tuple of ints may suffice, although you may need to get a little cleverer if there are ever any version strings that aren't entirely dotted numeric. -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
On 03/02/2015 01:38 PM, Charles Heizer wrote: Sorry, sortedlist = sorted(mylist , key=lambda elem: %s %s % (elem['name'], LooseVersion(elem['version'])), reverse=True) This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Please don't top-post. put your remarks after whatever quoting you do. You still haven't posted your LooseVersion() function source. I agree with Emile that it's likely to be the problem. -- DaveA -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries
Never mind, the light bulb finally went off. :-\ sortedlist = sorted(mylist , key=lambda elem: %s %s % ( elem['name'], (..join([i.zfill(5) for i in elem['version'].split(.)])) ), reverse=True) On Monday, March 2, 2015 at 10:40:30 AM UTC-8, Charles Heizer wrote: Sorry, sortedlist = sorted(mylist , key=lambda elem: %s %s % (elem['name'], LooseVersion(elem['version'])), reverse=True) This is what I was trying but LooseVersion() was not sorting version numbers like I thought it would. You will notice that Chrome version 40.0.2214.111 is higher than 40.0.2214.91 but in the end result it's not sorting it that way. Thanks, Charlie On Monday, March 2, 2015 at 10:32:40 AM UTC-8, Emile van Sebille wrote: On 3/2/2015 10:17 AM, Charles Heizer wrote: Hello, I'm new to python and I'm trying to find the right way to solve this issue I have. I'm trying to sort this list by name and then by version numbers. The problem I'm having is that I can not get the version numbers sorted with the highest at the top or sorted properly. mylist = [{'name': u'com.google.earth', 'version': u'7.1.2.2041'}, {'name': u'com.google.earth', 'version': u'7.1.2.2019'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.93'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.91'}, {'name': u'com.google.Chrome', 'version': u'40.0.2214.111'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.99'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.95'}, {'name': u'com.google.Chrome', 'version': u'39.0.2171.71'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.122'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.111'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.104'}, {'name': u'com.google.Chrome', 'version': u'38.0.2125.101'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.94'}, {'name': u'com.google.Chrome', 'version': u'37.0.2062.120'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.143'}, {'name': u'com.google.Chrome', 'version': u'36.0.1985.125'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.153'}, {'name': u'com.google.Chrome', 'version': u'35.0.1916.114'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.137'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.131'}, {'name': u'com.google.Chrome', 'version': u'34.0.1847.116'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.152'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.149'}, {'name': u'com.google.Chrome', 'version': u'33.0.1750.146'}, {'name': u'com.google.Chrome', 'version': u'32.0.1700.107'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.63'}, {'name': u'com.google.Chrome', 'version': u'31.0.1650.57'}] sortedlist = sorted(mylist , key=lambda x, y: x['name'] LooseVersion(elem['version'])), reverse=True) You'll need to fix LooseVersion or elem or both -- or show them so we can help. Emile Thanks, Charlie -- https://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
On Tue, Jan 12, 2010 at 11:45 PM, Nico Grubert nicogrub...@gmail.com wrote: Hi there I have the following list 'mylist' that contains some dictionaries: mylist = [{'title':'the Fog', 'id':1}, {'title':'The Storm', 'id':2}, {'title':'the bible', 'id':3}, {'title':'The thunder', 'id':4} ] mylist.sort(key = lambda d: d['title']) Use operator.itemgetter() to optimize in the unlikely event it becomes necessary. Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
Nico Grubert wrote: I have the following list 'mylist' that contains some dictionaries: mylist = [{'title':'the Fog', 'id':1}, {'title':'The Storm', 'id':2}, {'title':'the bible', 'id':3}, {'title':'The thunder', 'id':4} ] How I can sort (case insensitive) the list by the dictioary's 'title' key? The result should be this list: [{'title':'the bible', 'id':3}, {'title':'the Fog', 'id':1}, {'title':'The Storm', 'id':2}, {'title':'The thunder', 'id':4} ] I am using Python 2.4. Python 2.4.6 (#2, Mar 19 2009, 10:02:47) [GCC 4.3.3] on linux2 Type help, copyright, credits or license for more information. import locale locale.setlocale(locale.LC_ALL, ) 'de_DE.UTF-8' mylist = [{'title':'the Fog', 'id':1}, ...{'title':'The Storm', 'id':2}, ...{'title':'the bible', 'id':3}, ...{'title':'The thunder', 'id':4} ... ] mylist.sort(key=lambda item: locale.strxfrm(item[title])) import pprint pprint.pprint(mylist) [{'id': 3, 'title': 'the bible'}, {'id': 1, 'title': 'the Fog'}, {'id': 2, 'title': 'The Storm'}, {'id': 4, 'title': 'The thunder'}] Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
On Wed, Jan 13, 2010 at 2:41 AM, Chris Rebert c...@rebertia.com wrote: On Tue, Jan 12, 2010 at 11:45 PM, Nico Grubert nicogrub...@gmail.com wrote: Hi there I have the following list 'mylist' that contains some dictionaries: mylist = [{'title':'the Fog', 'id':1}, {'title':'The Storm', 'id':2}, {'title':'the bible', 'id':3}, {'title':'The thunder', 'id':4} ] mylist.sort(key = lambda d: d['title']) Er, that should have been mylist.sort(key = lambda d: d['title'].lower()) of course. Goes for more coffee Cheers, Chris -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
Nico Grubert nicogrub...@gmail.com writes: Hi there I have the following list 'mylist' that contains some dictionaries: mylist = [{'title':'the Fog', 'id':1}, {'title':'The Storm', 'id':2}, {'title':'the bible', 'id':3}, {'title':'The thunder', 'id':4} ] How I can sort (case insensitive) the list by the dictioary's 'title' key? mylist.sort(key=lambda x: x['title'].lower()) Florian -- http://www.florian-diesch.de/software/easygconf/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
Er, that should have been mylist.sort(key = lambda d: d['title'].lower()) of course. Thanks a lot for the tip, chris. Unfortunately, I only have Python 2.3.5 installed and can't upgrade to 2.4 due to an underliying application server. In python 2.3 the 'sort()' function does not excepts any keywords arguments (TypeError: sort() takes no keyword arguments), so is there a workaround? Regards Nico -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
Nico Grubert wrote: Er, that should have been mylist.sort(key = lambda d: d['title'].lower()) of course. Thanks a lot for the tip, chris. Unfortunately, I only have Python 2.3.5 installed and can't upgrade to 2.4 due to an underliying application server. In python 2.3 the 'sort()' function does not excepts any keywords arguments (TypeError: sort() takes no keyword arguments), so is there a workaround? There is a technique called decorate-sort-undecorate: 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 = Atem Äther ähnlich anders.split() print .join(sorted(items, key=lambda s: s.lower())) anders Atem Äther ähnlich print .join(sorted(items, key=lambda s: locale.strxfrm(s))) ähnlich anders Atem Äther The above may run on 2.3, but I actually ran it on 2.6. Peter -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
Peter Otten, 13.01.2010 13:25: items = Atem Äther ähnlich anders.split() print .join(sorted(items, key=lambda s: s.lower())) If you can make sure that 's' is either always a byte string or always a unicode string (which is good programming practice anyway), an unbound method can simplify (and speed up) the above, e.g. sorted(items, key=unicode.lower) Stefan -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: Sort list of dictionaries by key (case insensitive)
http://wiki.python.org/moin/HowTo/Sorting#Topicstobecovered Works fine. Thanks a lot for your help, Stefan. Regards Nico -- http://mail.python.org/mailman/listinfo/python-list