Basically, I like this idea and of course theoretically it has use cases. But
in the proposed form, it feels strongly curtailed. In practice, what does
it mean to be sorted?

[('a', 1),('b', 2),('bb', 4),('aaa', 3)]  # Is this list sorted?
[('a', 1),('aaa', 3),('b', 2),('bb', 4)]  # or this?
[('a', 1),('b', 2),('aaa', 3),('bb', 4)]  # or that?

The right answer is that they are all sorted by some means. So, if you
offer this __is_sorted__ attribute only for a very special case 1d list of
numbers - this makes no sense.  (Just re-read the recent thread, why .join
is the string method and not the *list *method). On the other hand If you
offer *some sort of a general protocol* storing a sort key or some other
useful information, then this is awesome! But is this achievable in
practice?

with kind regards,
-gdg

пн, 8 апр. 2019 г. в 05:38, Steven D'Aprano <st...@pearwood.info>:

> There are quite a few important algorithms which require lists to be
> sorted. For example, the bisect module, and for statistics median and
> other quantiles.
>
> Sorting a list is potentially expensive: while Timsort is very
> efficient, it is still ultimately an O(N log N) algorithm which limits
> how efficient it can be. Checking whether a list is sorted is O(N).
>
> What if we could check that lists were sorted in constant time?
>
> Proposal: let's give lists a dunder flag, __issorted__, that tracks
> whether the list is definitely sorted or not:
>
> - Empty lists, or lists with a single item, are created with
>   __issorted__ = True; lists with two or more items are created
>   with the flag set to False.
>
> - Appending or inserting items sets the flag to False.
>
> - Deleting or popping items doesn't change the flag.
>
> - Reversing the list doesn't change the flag.
>
> - Sorting it sets the flag to True. (The sort method should NOT
>   assume the list is sorted just because the flag is set.)
>
> Functions that require the list to be sorted can use the flag as a
> quick check:
>
>     if not alist.__issorted__:
>         alist.sort()
>     ...
>
> The flag will be writable, so that functions such as those in
> bisect can mark that they have kept the sorted invariant:
>
>
>     bisect.insort(alist, x)
>     assert alist.__issorted__
>
>
> Being writable, the flag is advisory, not a guarantee, and "consenting
> adults" applies. People can misuse the flag:
>
>     alist = [1, 4, 2, 0, 5]
>     alist.__issorted__ = True
>
> but then they have nobody to blame but themselves if they shoot
> themselves in the foot. That's no worse than the situation we have now,
> were you might pass an unsorted list to bisect.
>
> The flag doesn't guarantee that the list is sorted the way you want
> (e.g. biggest to smallest, by some key, etc) only that it has been
> sorted. Its up to the user to ensure they sort it the right way:
>
>     # Don't do this and expect it to work!
>     alist.sort(key=random.random)
>     bisect.insort(alist, 1)
>
>
> If you really want to be sure about the state of the list, you have to
> make a copy and sort it. But that's no different from the situation
> right now. But for those willing to assume "consenting adults", you
> might trust the flag and avoid sorting.
>
> Downsides:
>
> - Every list grows an extra attribute; however, given that lists are
>   already quite big data structures and are often over-allocated, I
>   don't think this will matter much.
>
> - insert(), append(), extend(), __setitem__() will be a tiny bit
>   slower due to the need to set the flag.
>
>
>
> Thoughts?
>
>
>
>
> --
> Steven
> _______________________________________________
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to