Skip to content

.sort() doesn't work correctly #605

Closed

Description

@supersational
[2,11].sort() 
# expected (python):
[2,11]
# result of JavaScript's [2,11].sort()  (used by Transcrypt.__runtime__.js in __sort__)
[11,2]

This is a classic JavaScript 'gotcha' since it will sort the elements as if they were strings, even if the elements are all numbers! It will sort correctly for most small numbers making it a tricky bug to catch as well.

Activity

  1. JdeH commented on Jan 10, 2019

    @JdeH
    Collaborator

    Indeed that's a problem, and not one that can be solved completely due to the lack of type info in JS.

    One pragmatic solution would be to regard anything that could be a number as indeed being a number. This would sort the list as [2, 11], but it would also produce ['2', '11'] as sorting result from a list of strings. Since the case of sorting list containing only numbers or only non-numerical strings will probably will be far more frequent than the case of sorting a list with both numbers and numerical strings, I think the latter would be acceptable.

    Type annotations could avoid ambiguity here, but I'd like to keep their use optional, since to many Python programmers they are still a bit alien... One way to do it is to consider a list that starts with a number or numerical string as containing only numbers. Still there would be some overhead in detecting that (and, but it would be better than having [11, 2] as result.

    Whatever solution is choosen, the limitations of it should receive attention in the documentation.

  2. self-assigned this
    on Jan 10, 2019
  3. faerot commented on Jan 17, 2019

    @faerot

    maybe resolving it just like you did with other overlapping pythoin/JS methods - adding py_sort and adding pragma which will enable pythonic sort with key function etc wherever necessary?

  4. supersational commented on Jan 30, 2019

    @supersational
    Author

    Hi thanks for looking into this, definitely agree with your goal of avoiding type annotations.

    Python's .sort() will throw an error unless all list elements are type "string" or a mix of number and boolean. So if the first element is a string type sort all as a string, if first element is a number (or boolean), sort all as numbers (and throw an error if any aren't of the required type).

  5. erelsgl commented on Nov 2, 2019

    @erelsgl

    I have the same issue. Is there a workaround?

  6. supersational commented on Nov 5, 2019

    @supersational
    Author

    You can fix by forcing a numerical sort

    a = [1,11,2,2.1,1.9]
    
    a.sort(key=float)
    print(a)
    # prints [1, 1.9, 2, 2.1, 11]
  7. assigned and unassigned on Jul 5, 2024
  8. JennaSys commented on Jul 7, 2024

    @JennaSys
    Collaborator

    Sorting with strings vs numbers to match CPython has been somewhat fixed in the dev_3.9.3 branch to be released in v3.9.3

    A limitation for now is that it will still allow comparisons between incompatible values like int and str where CPython would throw an error. Adding type validation to sorting to match CPython would add bloat to the runtime and likely be imperfect anyway. This can be revisited in the future if necessary.

  9. linked a pull request that will close this issueDev 3.9.3 #876on Jul 17, 2024
  10. JennaSys commented on Jul 17, 2024

    @JennaSys
    Collaborator

    Merged to master on PR #876

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions