For what it's worth, I've attached a patch that implements this as a prototype.

It's definitely not mergeable right now.  I'm not aware of any issues, but the code needs more error checking, and the coding style doesn't match cpython's.

Having said that, it's a 70-line change, so fixing that up should be trivial once the change has some agreement behind it.

Steve



On Wed, Jul 1, 2020 at 4:31 PM Stestagg <stestagg@gmail.com> wrote:
I'll try to unwind the rabbit holes a bit and suggest that the differences in opinion here boil down to:

Is it most useful to consider dict_keys/items/values as: (This doesn't mean what isinstance() returns, or what a previous pep has stated, just how one thinks about them):
 1. ordered collections that have some set-like operators added for convenience, (conceptually, if not exactly, class ...(Set, Sequence):)  but are missing a single method full Sequence interface (__getitem__)
or
 2. Sets that happen to have a stable/deterministic element order

My opinion is that, as of Python 3.7, they are effectively 1, even if the isinstance hooks haven't been updated.  I can see why people may think of them as 2. I don't have any desire to change minds on this :)


Semantic quibbling aside, My opinions/reasoning on the different options are the following:


* Do nothing:
-0.5: I can live with the current situation, some things I do infrequently will be slightly less convenient, but can work around easily.

* Add numeric `__getitem__` to `dict_*` view classes: 
+1  - This restores code that used to work in python 2, and makese some things a bit easier.  The O(n) behaviour is not ideal, but in my opinion is an acceptable compromise

* Add new method to dict class:
-1 This doesn't feel like a good solution to me.  Rather than continue to argue about the justification for why, let's just say its a personal judgement

I'm interested in any other opinions on these options

Steve



On Wed, Jul 1, 2020 at 3:24 PM Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Jul 01, 2020 at 01:36:34PM +0100, Stestagg wrote:
> On Wed, Jul 1, 2020 at 12:18 PM Steven D'Aprano <steve@pearwood.info> wrote:
>
> > On Tue, Jun 30, 2020 at 10:18:34AM +0100, Stestagg wrote:
> >
> > > This property is nice, as .keys() (for example) can operate like a
> > > set and give lots of convenience features.  However this doesn't
> > > really mean that these objects are trying to *be* sets in any
> > > meaning way,
> >
> > Please read the PEP:
> >
> > https://www.python.org/dev/peps/pep-3106/
> >
> > It was an explicit design choice to make them be set-like, not an
> > accident. The whole point was to offer a set interface.
>
>
> I'm pretty familiar with that pep, I'm not sure how knowledge of its
> contents affects this idea/discussion in any material way.

You: I don't think that dict views are trying to be sets.

Me: Dict views were designed right from the start to be like sets, as
described in the PEP.

You: I don't think the PEP is relevant.

Okay, whatever you say.


> The point being made,  was that the utility of trying to shoehorn the
> dict_* types into a Set pidgeon-hole is quite limited, as practicalities
> get in the way.

*shrug*

They seem to work pretty well for many uses. Perhaps they could be
better, but they are what they are, and there's no point pretending that
they aren't large-s Sets when they clearly are.

    py> from collections.abc import Set
    py> isinstance({}.items(), Set)
    True

This is not an accident, it is not a mistake, it wasn't forced on the
language because dicts used to be unordered. It was an intentional
design choice.

If you think that *dict views are set-like* being an intentional choice
is not important to the discussion, what do you consider important?

As far as I am concerned, making dict views into sequences by making
them indexable should be ruled out. They were intended to be set-like,
not sequence-like, and that is the end of the story. Adding indexing
onto them is bolting on an API that was never part of the design.

I still don't think there are any compelling use-cases for indexing
dicts, but if there are, we should offer a getter method on the dict
object itself, not try to turn dict views into a hybrid set+sequence.
Change my mind.


> > > I don't think inventing new methods for emulating __getitem__ is that
> > > useful here, there is a well established standard for getting items from
> > > a container by index, I think we should use it :).
> >
> > We can't use dict[index] because the index can also be a key:
> >
> >     d = {'a': None, 'b': None, 0: 999}
> >     d[0]  # return 'a' or 999?
>
> The currently discussed option is for adding`__getitem__` to the
> dict_keys/dict_items/dict_values types, *NOT* the base `dict` type.

You: We shouldn't invent a new way of indexing containers.

Also you: Let's invent a new way of indexing containers (subscripting on
dict views).

So which is it?

Subscripting on the dict object is ruled out because it is ambiguous.
Here are three possible choices (there may be others):

- Do nothing, we don't need this functionality, there are no compelling
  use-cases for it. Passing dict keys to random.choice is not a
  compelling use-case.

- Add a new interface by making dict views a hybrid set+sequence.

- Add a new getter method on the dict itself.

Aside from the first do-nothing option, one way or the other we're
adding a new way of indexing the object we actually want to index,
namely the dict.

The choice is between a getter interface, and a subscript interface on a
proxy (a dict view). Dicts already offer getter interfaces (dict.get,
dict.setdefault) so it is not like calling dict methods is unheard of.


[...]
> The point wasn't that: "It's atypical so we can ignore it", but rather:
> "It's faster/better, but seldom available to be used, here's how we do it
> for the more common case..."

Okay, thanks for the correction.


--
Steven
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/A34NF6R6JTSQAZLIU6IKN4UWC2L2WANO/
Code of Conduct: http://python.org/psf/codeofconduct/