Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #86766 > unrolled thread
| Started by | Charles Heizer <ceh329@gmail.com> |
|---|---|
| First post | 2015-03-02 10:17 -0800 |
| Last post | 2015-03-03 18:55 +1100 |
| Articles | 16 — 9 participants |
Back to article view | Back to comp.lang.python
Sort list of dictionaries Charles Heizer <ceh329@gmail.com> - 2015-03-02 10:17 -0800
Re: Sort list of dictionaries Emile van Sebille <emile@fenx.com> - 2015-03-02 10:31 -0800
Re: Sort list of dictionaries Charles Heizer <ceh329@gmail.com> - 2015-03-02 10:38 -0800
Re: Sort list of dictionaries Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-02 11:55 -0700
Re: Sort list of dictionaries Charles Heizer <ceh329@gmail.com> - 2015-03-02 10:58 -0800
Re: Sort list of dictionaries Peter Otten <__peter__@web.de> - 2015-03-02 20:23 +0100
Re: Sort list of dictionaries Charles Heizer <ceh329@gmail.com> - 2015-03-03 07:56 -0800
Re: Sort list of dictionaries Chris Angelico <rosuav@gmail.com> - 2015-03-04 03:09 +1100
Re: Sort list of dictionaries Paul Moore <p.f.moore@gmail.com> - 2015-03-03 08:48 -0800
Re: Sort list of dictionaries Peter Otten <__peter__@web.de> - 2015-03-03 18:44 +0100
Re: Sort list of dictionaries Dave Angel <davea@davea.name> - 2015-03-02 13:59 -0500
Re: Sort list of dictionaries Jason Friedman <jsf80238@gmail.com> - 2015-03-02 22:33 -0700
Re: Sort list of dictionaries Chris Angelico <rosuav@gmail.com> - 2015-03-03 18:07 +1100
Re: Sort list of dictionaries Jason Friedman <jsf80238@gmail.com> - 2015-03-03 07:45 -0700
Re: Sort list of dictionaries Chris Angelico <rosuav@gmail.com> - 2015-03-04 01:50 +1100
Re: Sort list of dictionaries Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-03 18:55 +1100
| From | Charles Heizer <ceh329@gmail.com> |
|---|---|
| Date | 2015-03-02 10:17 -0800 |
| Subject | Sort list of dictionaries |
| Message-ID | <f1a339d0-0386-43ba-b6b4-1aee39d75581@googlegroups.com> |
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)
Thanks,
Charlie
[toc] | [next] | [standalone]
| From | Emile van Sebille <emile@fenx.com> |
|---|---|
| Date | 2015-03-02 10:31 -0800 |
| Message-ID | <mailman.56.1425321135.13471.python-list@python.org> |
| In reply to | #86766 |
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
>
[toc] | [prev] | [next] | [standalone]
| From | Charles Heizer <ceh329@gmail.com> |
|---|---|
| Date | 2015-03-02 10:38 -0800 |
| Message-ID | <946797be-10e6-433b-9411-2db0d5697ac8@googlegroups.com> |
| In reply to | #86767 |
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
> >
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-03-02 11:55 -0700 |
| Message-ID | <mailman.58.1425322577.13471.python-list@python.org> |
| In reply to | #86768 |
On Mon, Mar 2, 2015 at 11:38 AM, Charles Heizer <ceh329@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.
[toc] | [prev] | [next] | [standalone]
| From | Charles Heizer <ceh329@gmail.com> |
|---|---|
| Date | 2015-03-02 10:58 -0800 |
| Message-ID | <8ccd65d8-3f1f-41ac-9092-9b0832d2fc49@googlegroups.com> |
| In reply to | #86768 |
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
> > >
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-03-02 20:23 +0100 |
| Message-ID | <mailman.61.1425324201.13471.python-list@python.org> |
| In reply to | #86772 |
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 > 99999 ;)
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)
[toc] | [prev] | [next] | [standalone]
| From | Charles Heizer <ceh329@gmail.com> |
|---|---|
| Date | 2015-03-03 07:56 -0800 |
| Message-ID | <432a0d61-a8ba-46ca-bc53-318e234fe168@googlegroups.com> |
| In reply to | #86778 |
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 > 99999 ;)
>
> 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?
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-04 03:09 +1100 |
| Message-ID | <mailman.22.1425398950.21433.python-list@python.org> |
| In reply to | #86851 |
On Wed, Mar 4, 2015 at 2:56 AM, Charles Heizer <ceh329@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.
[toc] | [prev] | [next] | [standalone]
| From | Paul Moore <p.f.moore@gmail.com> |
|---|---|
| Date | 2015-03-03 08:48 -0800 |
| Message-ID | <18d22144-9fce-40a5-9be5-eeec43194394@googlegroups.com> |
| In reply to | #86853 |
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
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-03-03 18:44 +0100 |
| Message-ID | <mailman.23.1425404702.21433.python-list@python.org> |
| In reply to | #86851 |
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 > 99999 ;)
>>
>> 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.
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2015-03-02 13:59 -0500 |
| Message-ID | <mailman.59.1425322796.13471.python-list@python.org> |
| In reply to | #86768 |
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
[toc] | [prev] | [next] | [standalone]
| From | Jason Friedman <jsf80238@gmail.com> |
|---|---|
| Date | 2015-03-02 22:33 -0700 |
| Message-ID | <mailman.2.1425360823.21433.python-list@python.org> |
| In reply to | #86768 |
>> 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
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-03 18:07 +1100 |
| Message-ID | <mailman.4.1425366433.21433.python-list@python.org> |
| In reply to | #86768 |
On Tue, Mar 3, 2015 at 4:33 PM, Jason Friedman <jsf80238@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 miiiiiiiight 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
[toc] | [prev] | [next] | [standalone]
| From | Jason Friedman <jsf80238@gmail.com> |
|---|---|
| Date | 2015-03-03 07:45 -0700 |
| Message-ID | <mailman.18.1425393922.21433.python-list@python.org> |
| In reply to | #86768 |
On Tue, Mar 3, 2015 at 12:07 AM, Chris Angelico <rosuav@gmail.com> wrote:
> Heh, I think that miiiiiiiight 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.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-04 01:50 +1100 |
| Message-ID | <mailman.19.1425394252.21433.python-list@python.org> |
| In reply to | #86768 |
On Wed, Mar 4, 2015 at 1:45 AM, Jason Friedman <jsf80238@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
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-03 18:55 +1100 |
| Message-ID | <54f568de$0$2877$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #86766 |
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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web