Skip to content

Add keylist argument to list.sort #142105

@dg-pb

Description

@dg-pb

Feature or enhancement

Proposal:

def sorted(iterable, /, *, key=None, keylist=None, reverse=False):
    ...

keylist is an extension that allows providing keys to list.sort that will be used for sorting.
This allows bypassing key generation via callable key argument or using zip with itemgetter in situations where possible.
The above are all relatively expensive operations, thus performance gain is non-trivial.

keylist accepts list, which will be mutated as part of sorting.
To prevent mutation of the input (or to supply arbitrary iterable), make a copy:

a.sort(keylist=list(my_keys))

List of examples and benchmarks is present in discourse thread.

TLDR: These are 3 main takeaways:

  1. Faster argsort without needing to use dunder method
# Current one best way
indices = sorted(range(N), key=seq.__getitem__)    # 32 ms (100K ints)
# After this:
indices = sorted(range(N), keylist=list(seq))      # 26 ms (100K ints)
  1. Non-trivial performance for dict sorting (or any other problem that is of the same nature)

Performance improvement against current alternative is 2-5x.

keys = list(d)
values = list(d.values())
values.sort(keylist=keys)
  1. Generally better performance whenever keylist is ready or faster ways to construct it are available
values = list(range(100_000))
%timeit list(map(lambda x: x % 10, l))  # 7.71 ms (What happens via `key`)
%timeit [x % 10 for x in l]             # 3.23 ms (If could be done manually)

In short, it provides an entry into list.sort function that makes it possible to take faster path in many cases where input list is not the same as sort keys.

Has this already been discussed elsewhere?

I have already discussed this feature proposal on Discourse

Links to previous discussion of this feature:

https://discuss.python.org/t/allow-sorted-to-take-list-for-key-argument/105106

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions