Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #106387 > unrolled thread

Sorting a list

Started byDFS <nospam@dfs.com>
First post2016-04-03 14:30 -0400
Last post2016-04-04 16:12 +0200
Articles 7 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Sorting a list DFS <nospam@dfs.com> - 2016-04-03 14:30 -0400
    Re: Sorting a list DFS <nospam@dfs.com> - 2016-04-03 14:34 -0400
    Re: Sorting a list Peter Otten <__peter__@web.de> - 2016-04-03 21:31 +0200
      Re: Sorting a list DFS <nospam@dfs.com> - 2016-04-03 16:08 -0400
        Re: Sorting a list Peter Otten <__peter__@web.de> - 2016-04-04 08:56 +0200
        Re: Sorting a list Random832 <random832@fastmail.com> - 2016-04-04 09:40 -0400
        Re: Sorting a list Peter Otten <__peter__@web.de> - 2016-04-04 16:12 +0200

#106387 — Sorting a list

FromDFS <nospam@dfs.com>
Date2016-04-03 14:30 -0400
SubjectSorting a list
Message-ID<ndrn97$bco$1@dont-email.me>
cntText = 60
cntBool = 20
cntNbrs = 30
cntDate = 20
cntBins = 20

strText = "  text:     "
strBool = "  boolean:  "
strNbrs = "  numeric:  "
strDate = "  date-time:"
strBins = "  binary:   "

colCounts = [(cntText,strText) , (cntBool,strBool), (cntNbrs,strNbrs) , 
(cntDate,strDate) , (cntBins,strBins)]

# sort by alpha, then by column type count descending
colCounts.sort(key=lambda x: x[1])
colCounts.sort(key=lambda x: x[0], reverse=True)
for key in colCounts: print key[1], key[0]]

-------------------------------------------------

Output (which is exactly what I want):

   text:      60
   numeric:   30
   binary:    20
   boolean:   20
   date-time: 20

-------------------------------------------------


But, is there a 1-line way to sort and print?


Thanks!


[toc] | [next] | [standalone]


#106389

FromDFS <nospam@dfs.com>
Date2016-04-03 14:34 -0400
Message-ID<ndrni3$c4b$1@dont-email.me>
In reply to#106387
On 4/3/2016 2:30 PM, DFS wrote:
> cntText = 60
> cntBool = 20
> cntNbrs = 30
> cntDate = 20
> cntBins = 20
>
> strText = "  text:     "
> strBool = "  boolean:  "
> strNbrs = "  numeric:  "
> strDate = "  date-time:"
> strBins = "  binary:   "
>
> colCounts = [(cntText,strText) , (cntBool,strBool), (cntNbrs,strNbrs) ,
> (cntDate,strDate) , (cntBins,strBins)]
>
> # sort by alpha, then by column type count descending
> colCounts.sort(key=lambda x: x[1])
> colCounts.sort(key=lambda x: x[0], reverse=True)
> for key in colCounts: print key[1], key[0]]
>
> -------------------------------------------------
>
> Output (which is exactly what I want):
>
>    text:      60
>    numeric:   30
>    binary:    20
>    boolean:   20
>    date-time: 20
>
> -------------------------------------------------
>
>
> But, is there a 1-line way to sort and print?

Meant to include this example:

print {i:os.strerror(i) for i in sorted(errno.errorcode)}



> Thanks!
>
>
>

[toc] | [prev] | [next] | [standalone]


#106394

FromPeter Otten <__peter__@web.de>
Date2016-04-03 21:31 +0200
Message-ID<mailman.408.1459711883.28225.python-list@python.org>
In reply to#106387
DFS wrote:

> cntText = 60
> cntBool = 20
> cntNbrs = 30
> cntDate = 20
> cntBins = 20
> 
> strText = "  text:     "
> strBool = "  boolean:  "
> strNbrs = "  numeric:  "
> strDate = "  date-time:"
> strBins = "  binary:   "
> 
> colCounts = [(cntText,strText) , (cntBool,strBool), (cntNbrs,strNbrs) ,
> (cntDate,strDate) , (cntBins,strBins)]
> 
> # sort by alpha, then by column type count descending
> colCounts.sort(key=lambda x: x[1])
> colCounts.sort(key=lambda x: x[0], reverse=True)
> for key in colCounts: print key[1], key[0]]
> 
> -------------------------------------------------
> 
> Output (which is exactly what I want):
> 
>    text:      60
>    numeric:   30
>    binary:    20
>    boolean:   20
>    date-time: 20
> 
> -------------------------------------------------
> 
> 
> But, is there a 1-line way to sort and print?

Yes, but I would not recommend it. You can replace the sort() method 
invocations with nested calls of sorted() and instead of

for item in items:
    print convert_to_str(item)

use

print "\n".join(convert_to_str(item) for item in items)

Putting it together:

>>> from operator import itemgetter as get
>>> print "\n".join("{1} {0}".format(*p) for p in sorted(
... sorted(colCounts, key=get(1)), key=get(0), reverse=True))
  text:      60
  numeric:   30
  binary:    20
  boolean:   20
  date-time: 20

You could also cheat and use

lambda v: (-v[0], v[1])

and a single sorted().

[toc] | [prev] | [next] | [standalone]


#106402

FromDFS <nospam@dfs.com>
Date2016-04-03 16:08 -0400
Message-ID<ndrt29$36l$1@dont-email.me>
In reply to#106394
On 4/3/2016 3:31 PM, Peter Otten wrote:
> DFS wrote:
>
>> cntText = 60
>> cntBool = 20
>> cntNbrs = 30
>> cntDate = 20
>> cntBins = 20
>>
>> strText = "  text:     "
>> strBool = "  boolean:  "
>> strNbrs = "  numeric:  "
>> strDate = "  date-time:"
>> strBins = "  binary:   "
>>
>> colCounts = [(cntText,strText) , (cntBool,strBool), (cntNbrs,strNbrs) ,
>> (cntDate,strDate) , (cntBins,strBins)]
>>
>> # sort by alpha, then by column type count descending
>> colCounts.sort(key=lambda x: x[1])
>> colCounts.sort(key=lambda x: x[0], reverse=True)
>> for key in colCounts: print key[1], key[0]]
>>
>> -------------------------------------------------
>>
>> Output (which is exactly what I want):
>>
>>     text:      60
>>     numeric:   30
>>     binary:    20
>>     boolean:   20
>>     date-time: 20
>>
>> -------------------------------------------------
>>
>>
>> But, is there a 1-line way to sort and print?
>
> Yes, but I would not recommend it. You can replace the sort() method
> invocations with nested calls of sorted() and instead of
>
> for item in items:
>      print convert_to_str(item)
>
> use
>
> print "\n".join(convert_to_str(item) for item in items)
>
> Putting it together:
>
>>>> from operator import itemgetter as get
>>>> print "\n".join("{1} {0}".format(*p) for p in sorted(
> ... sorted(colCounts, key=get(1)), key=get(0), reverse=True))

Kind of clunky looking.  Is that why don't you recommend it?




>    text:      60
>    numeric:   30
>    binary:    20
>    boolean:   20
>    date-time: 20
>
> You could also cheat and use
>
> lambda v: (-v[0], v[1])
>
> and a single sorted().

That works well.  Why is it 'cheating'?


Thanks for the reply.

[toc] | [prev] | [next] | [standalone]


#106424

FromPeter Otten <__peter__@web.de>
Date2016-04-04 08:56 +0200
Message-ID<mailman.2.1459753001.32530.python-list@python.org>
In reply to#106402
DFS wrote:

> On 4/3/2016 3:31 PM, Peter Otten wrote:

>>>>> from operator import itemgetter as get
>>>>> print "\n".join("{1} {0}".format(*p) for p in sorted(
>> ... sorted(colCounts, key=get(1)), key=get(0), reverse=True))
> 
> Kind of clunky looking.  Is that why don't you recommend it?

That, and you produce two intermediate lists and an intermediate string. For 
larger input data this may produce significant overhead.

>> You could also cheat and use
>>
>> lambda v: (-v[0], v[1])
>>
>> and a single sorted().
> 
> That works well.  Why is it 'cheating'?

On second thought it isn't ;)

[toc] | [prev] | [next] | [standalone]


#106438

FromRandom832 <random832@fastmail.com>
Date2016-04-04 09:40 -0400
Message-ID<mailman.16.1459777245.32530.python-list@python.org>
In reply to#106402
On Mon, Apr 4, 2016, at 02:56, Peter Otten wrote:
> > That works well.  Why is it 'cheating'?
> 
> On second thought it isn't ;)

It does require a numeric type, though. There are lots of types that are
orderable but do not have a negation operator that provides a key with
reversed ordering.

[toc] | [prev] | [next] | [standalone]


#106441

FromPeter Otten <__peter__@web.de>
Date2016-04-04 16:12 +0200
Message-ID<mailman.19.1459779546.32530.python-list@python.org>
In reply to#106402
Random832 wrote:

> On Mon, Apr 4, 2016, at 02:56, Peter Otten wrote:
>> > That works well.  Why is it 'cheating'?
>> 
>> On second thought it isn't ;)
> 
> It does require a numeric type, though. There are lots of types that are
> orderable but do not have a negation operator that provides a key with
> reversed ordering.

If you are willing to accept the overhead you can use a wrapper class:

>>> import functools
>>> @functools.total_ordering
... class neg:
...     def __init__(self, key):
...         self.key = key
...     def __lt__(self, other):
...         return other.key < self.key
... 
>>> sorted("abcde", key=neg)
['e', 'd', 'c', 'b', 'a']

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web