On Mon, Feb 8, 2021 at 4:21 PM Random832 <random...@fastmail.com> wrote:
>
> > On Sat, Feb 6, 2021 at 5:21 PM Random832 <random...@fastmail.com> wrote:
> > >
> > > While we're on the subject of assignment expression limitations, I've 
> > > occasionally wanted to write something like
> > >
> > > try:
> > >     return a_dict[key]
> > > except KeyError:
> > >     return (a_dict[key] := expression to construct value)
>
> On Sat, Feb 6, 2021, at 01:26, Chris Angelico wrote:
> >
> > That's what the __missing__ method is for.
>
> Requires a dict subclass

That shouldn't be a big deal in most situations.

> Requires that the value be determinable from the key alone [rather than any 
> other variables available in the function containing the above code]

True, but in many situations that IS the case. You're stipulating a
situation where:

1) The construction isn't a simple no-arg function (so you can't use
defaultdict)
2) The construction can't be figured out from the key alone
3) The cost of construction is high (so you can't use setdefault)
4) There are multiple places where you'd want this behaviour (so you
can't just try/except it)

Seems a tad narrow to me. Got an actual use-case for this?

> On Sat, Feb 6, 2021, at 01:50, Brendan Barnwell wrote:
> >       You can already do that with `return a_dict.setdefault(key,
> > your_expression_here)`.  If the expression is expensive to evaluate you
> > can use a short-circuiting conditional expression to guard it.
>
> How exactly would you use a short-circuiting conditional expression to do 
> this?
>
> If you're suggesting `... if key not in a_dict else ...` this creates a race 
> condition, and also involves checking the key in the dictionary twice.

Only against deletion. You could use:

a_dict[key] if key in a_dict else a_dict.setdefault(key, big_long_epr)

and you're guaranteed that it will use the existing value if it
exists. It's possible that the key exists at the condition and then
has been deleted before the subscript, but then you have to ask what
would happen if you did a regular setdefault and then the key was
deleted, and at this point, it's entirely down to the application's
semantics (what does it MEAN if something's been deleted while
something else is trying to auto-add it?).

Checking if a key is in a dict is extremely cheap. Dicts are
fundamental to Python, and every implementation will have a highly
optimized dict such that you shouldn't need to worry about that kind
of cost.

> Perhaps a constructdefault method could be added to dict, broadly equivalent 
> to
>
> def constructdefault(self, func):
>     try:
>         return self[key]
>     except KeyError:
>         return (self[key] := func())
>
> you could use self[key] = value = func(); return value; and the same in the 
> original [not part of dict class] snippet I posted above, but the point is 
> this seems so much like exactly the sort of use case that := is intended for, 
> that it comes across as weird that it's not usable.
>

During discussion of PEP 463, one of the points raised was that many
situations like this might be better spelled as exception expressions.
That was largely shot down by the fact that, in actual usage, methods
like setdefault are FAR easier to work with. I think the same applies
here; rather than shoehorning assignment expressions into this job,
figure out why it is that both __missing__ and setdefault() aren't
suitable, and see if THAT problem can be solved.

I've been using assignment expressions since they were added to the
language (my primary Python interpreter has, for a number of years,
been a master branch build), and they've been incredibly useful, but I
have never once run into a situation where the restrictions cause me
problems.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/TTIWDJ7WBNDGZUUUS2P5DLM5CN6ND776/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to