[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Benjamin Peterson

Benjamin Peterson added the comment:

On Wed, Apr 29, 2015, at 13:25, Sergey B Kirpichev wrote:
 
 Sergey B Kirpichev added the comment:
 
 On Wed, Apr 29, 2015 at 03:25:19PM +, Benjamin Peterson wrote:
  So, basically you need a base case for recursion? What's wrong with
  explicitly writing that out?
 
 Because it's complex (and costly).  This is not a trivial test and
 I don't see reasons to fix that is not broken.  And it will be difficult
 to explain for readers: remember, I need this exceptional case only in
 the world with a strange Python's convention (Python try to sort a list
 when it doesn't make sense).
 
 Mathematical algorithm is not broken - programming language is.
 
 Here is C:
 https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/msort.c;#l45
 Here is Ruby:
 https://github.com/ruby/ruby/blob/trunk/array.c#L2454

I don't understand the analogy, since neither of these two have key
functions.

 
  It's practical if you have a broken key function and test it with a one
  element list.
 
 It's silly to test key function on a single-element list *only*.
 
   BTW, why this issue was closed?
  
  3 of us agreed this doesn't seem like a suitable change.
 
 And 1 seems to be ok with patch.  Is this just a question of
 number of votes?

I should also clarify that Raymond and Mark and responsible for
maintaining most of the algorithmic/data structure code in Python.

 
 At least, please consider this as a documentation issue.  That ...
 feature may be obvious for a Python developer, but not for
 mathematician (as well as ordinary Python user).

This is probably impossible to prove either way.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Paul Moore

Paul Moore added the comment:

I think the documentation is fine:


The key corresponding to each item in the list is calculated once and then used 
for the entire sorting process.


This corresponds with the standard decorate-sort-undecorate approach to 
handling key functions in sorts. It's a common computer science technique, 
possibly not as familiar to a mathematician, but regardless, the docs clearly 
state that the key is calculated for each item.

Your existing code, with a check for Omega having length 1 and omitting the 
sort in that case, looks entirely reasonable to me. Maybe you could add a 
comment Avoid a costly calculation of the key when length is 1, as we know we 
don't need to sort then and leave it at that.

--
nosy: +paul.moore

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Paul Moore

Paul Moore added the comment:

On 29 April 2015 at 19:42, Sergey B Kirpichev rep...@bugs.python.org wrote:
 It's a common computer science technique

 Could you provide any language that avoid this optimization?

 Here is Perl 5:
 http://perl5.git.perl.org/perl.git/blob/HEAD:/pp_sort.c#l367

 (third example)

But that's a sort without a key. In Perl you do a key sort via:

@sorted = map  { $_-[0] }
  sort { $a-[1] = $b-[1] } # use numeric comparison
  map  { [$_, length($_)] }# calculate the length of the string
   @unsorted;

(From http://en.wikipedia.org/wiki/Schwartzian_transform). That
computes the keys first, and would compute the key for a list of
length 1, just like Python does. It's just that Python bundles that
whole construct into the key= argument.

But it's your choice - if this is a big enough deal to put you off
Python, I guess no-one will be able to stop you. The fact of the
matter is that what Python does is documented behaviour, and the
benefit (small) isn't worth the cost of making a change (which would
only be in Python 3.5 and later anyway, as it's a backward
incompatible change, not a bug fix).

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Sergey B Kirpichev added the comment:

On Wed, Apr 29, 2015 at 03:25:19PM +, Benjamin Peterson wrote:
 So, basically you need a base case for recursion? What's wrong with
 explicitly writing that out?

Because it's complex (and costly).  This is not a trivial test and
I don't see reasons to fix that is not broken.  And it will be difficult
to explain for readers: remember, I need this exceptional case only in
the world with a strange Python's convention (Python try to sort a list
when it doesn't make sense).

Mathematical algorithm is not broken - programming language is.

Here is C:
https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/msort.c;#l45
Here is Ruby:
https://github.com/ruby/ruby/blob/trunk/array.c#L2454

 It's practical if you have a broken key function and test it with a one
 element list.

It's silly to test key function on a single-element list *only*.

  BTW, why this issue was closed?
 
 3 of us agreed this doesn't seem like a suitable change.

And 1 seems to be ok with patch.  Is this just a question of
number of votes?

At least, please consider this as a documentation issue.  That ...
feature may be obvious for a Python developer, but not for
mathematician (as well as ordinary Python user).

When key function value has no sense at all - it's not clear from
the documentation, that the key function will be called.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Sergey B Kirpichev added the comment:

On Wed, Apr 29, 2015 at 05:44:22PM +, Paul Moore wrote:
 I think the documentation is fine:
 
 The key corresponding to each item in the list is calculated once and then 
 used for the entire sorting process.
 

Does any sorting process make sense for [1] or []?!  No, it
isn't.  So, it's not clear if this process started at all.

This not just mine opinion - most computer languages
implement the quick exit in question (see examples above).

 It's a common computer science technique

Could you provide any language that avoid this optimization?

Here is Perl 5:
http://perl5.git.perl.org/perl.git/blob/HEAD:/pp_sort.c#l367

(third example)

 Your existing code, with a check for Omega having length 1 and omitting
 the sort in that case, looks entirely reasonable to me.

(Well, then I should look for other languages, if Python devs
insist in doing useless work...)

 Maybe you could add a comment Avoid a costly calculation of the
 key when length is 1, as we know we don't need to sort then

I sure, for most people - the idea of sorting list with one
element will look crazy.  There is no room for any costly
calculations.  (Common sense, nothing more.)  So, such comment
will add more questions...

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Changes by Sergey B Kirpichev skirpic...@gmail.com:


Added file: 
http://bugs.python.org/file39232/0001-list.sort-Add-quick-exit-if-length-of-list-1.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Sergey B Kirpichev added the comment:

On Wed, Apr 29, 2015 at 06:51:21PM +, Paul Moore wrote:
 But that's a sort without a key.

Why it does matter?  It have quick exit.  For same reasons - Python could...

 In Perl you do a key sort via:

That's just your implementation.  But we could add here a
quick exit as well.

 The fact of the matter is that what Python does is documented behaviour

No.  Unless you absolutely sure - all readers think that sorting
process starts even for trivial lists.  No reasons to believe in that
nonsense - as you could see from sorting implementations in other languages.

 benefit (small) isn't worth the cost of making a change (which would
 only be in Python 3.5 and later anyway

It's easy for users (i.e. me) to backport this feature (i.e. make wrapper for
sorted()).  Benefit is small, I admit, but why not remove unnecessary
restrictions from the language?  I hope, I did my best to explain why.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

New submission from Sergey B Kirpichev:

If there is nothing to sort (i.e. one item), why call key function at all?

In my practical situation, simplest key() function will lead to recursion in 
case of such trivial lists.  I can make similar cmp-type function (i.e. 
mycmp=lambda a, b: cmp(key(a), key(b))) and then wrap this with cmp_to_key.  
But that looks silly.

Simple test case:
$ cat a.py
a = [1]

def spam(x):
raise Exception

a.sort(key=spam)
print(a)
$ python a.py 
Traceback (most recent call last):
  File a.py, line 6, in module
a.sort(key=spam)
  File a.py, line 4, in spam
raise Exception
Exception

--
components: Interpreter Core
files: trivial-sorting-py3.patch
keywords: patch
messages: 24
nosy: Sergey.Kirpichev
priority: normal
severity: normal
status: open
title: list.sort() should do quick exit if len(list) = 1
type: behavior
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6
Added file: http://bugs.python.org/file39231/trivial-sorting-py3.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Stéphane Wirtel

Stéphane Wirtel added the comment:

The patch is ok for me,

--
nosy: +matrixise, r.david.murray

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Sergey B Kirpichev added the comment:

should I add a regression test?

If so, where?  ./Lib/test/test_sort.py?

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Raymond Hettinger

Raymond Hettinger added the comment:

FWIW, I don't think this is worth special casing.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Serhiy Storchaka

Changes by Serhiy Storchaka storch...@gmail.com:


--
nosy: +rhettinger, tim.peters
stage:  - patch review
type: behavior - performance
versions:  -Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.6

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Benjamin Peterson

Benjamin Peterson added the comment:

Why does your key function depend on the size of the list? That seems like the 
root of the problem. Considering calling the key function is observable 
behavior, I don't think this should be changed. The patch makes behavior 
list.sort() inconsistent.

--
nosy: +benjamin.peterson

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Stéphane Wirtel

Stéphane Wirtel added the comment:

Yep, add a regression test.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Benjamin Peterson

Benjamin Peterson added the comment:

On Wed, Apr 29, 2015, at 11:03, Sergey B Kirpichev wrote:
 
 Sergey B Kirpichev added the comment:
 
 On Wed, Apr 29, 2015 at 02:32:34PM +, Benjamin Peterson wrote:
  Why does your key function depend on the size of the list?
 
 Because it's a real life.  Here is the code:
 https://github.com/skirpichev/omg/blob/gruntz-use-subs/sympy/series/gruntz.py#L337
 
 Algorithm is recursive and computation of MRV set will be finished only
 if I add an exceptional case for len(Omega).  Or even more ugly solution
 with cmp-style function:
 https://github.com/skirpichev/omg/blob/efc70377639f78fc0f246629989056cb80a71923/sympy/series/gruntz.py#L339

So, basically you need a base case for recursion? What's wrong with
explicitly writing that out?

 
  Considering calling the key function is observable behavior, I don't think 
  this
  should be changed. The patch makes behavior list.sort() inconsistent.
 
 Yes, in some sense.
 
 On another hand, it's reasonable to believe that key function will be
 called iff we need one.  But if there is nothing to sort at all - why do
 sorting, why you want to call key function?  Looks irrational to me.
 
 Last by not least.  Why the return value of the key function *must*
 be defined in this case?  Just a hidden, undocumented restriction and
 has no practical value.

It's practical if you have a broken key function and test it with a one
element list.

 
 BTW, why this issue was closed?

3 of us agreed this doesn't seem like a suitable change.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Mark Dickinson

Mark Dickinson added the comment:

 I should also clarify that Raymond and Mark and responsible for
maintaining most of the algorithmic/data structure code in Python.

Well, Raymond at least.  I plead not guilty; I think you're confusing me with 
someone else. :-)

But for this issue, this mathematician prefers the simple invariant that the 
key function is called exactly once per list item. If your key function doesn't 
work for one of those items for some reason, that sounds like a problem with 
the key function rather than a reason to change the sorting implementation.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Mark Dickinson

Mark Dickinson added the comment:

 Considering calling the key function is observable behavior, I don't think 
 this should be changed.

+1

--
nosy: +mark.dickinson

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Benjamin Peterson

Changes by Benjamin Peterson benja...@python.org:


--
resolution:  - rejected
status: open - closed

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue24075] list.sort() should do quick exit if len(list) = 1

2015-04-29 Thread Sergey B Kirpichev

Sergey B Kirpichev added the comment:

On Wed, Apr 29, 2015 at 02:32:34PM +, Benjamin Peterson wrote:
 Why does your key function depend on the size of the list?

Because it's a real life.  Here is the code:
https://github.com/skirpichev/omg/blob/gruntz-use-subs/sympy/series/gruntz.py#L337

Algorithm is recursive and computation of MRV set will be finished only
if I add an exceptional case for len(Omega).  Or even more ugly solution
with cmp-style function:
https://github.com/skirpichev/omg/blob/efc70377639f78fc0f246629989056cb80a71923/sympy/series/gruntz.py#L339

 Considering calling the key function is observable behavior, I don't think 
 this
 should be changed. The patch makes behavior list.sort() inconsistent.

Yes, in some sense.

On another hand, it's reasonable to believe that key function will be
called iff we need one.  But if there is nothing to sort at all - why do
sorting, why you want to call key function?  Looks irrational to me.

Last by not least.  Why the return value of the key function *must*
be defined in this case?  Just a hidden, undocumented restriction and
has no practical value.

BTW, why this issue was closed?

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue24075
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com