On Mon, Dec 28, 2020 at 11:36 PM Christopher Barker <python...@gmail.com>
wrote:

> On Mon, Dec 28, 2020 at 12:33 PM Guido van Rossum <gu...@python.org>
> wrote:
>
>> On Mon, Dec 28, 2020 at 12:15 PM Christopher Barker <python...@gmail.com>
>> wrote:
>>
>>> Though frankly, I would rather have had it use .items() -- seems more
>>> efficient to me, and you do need both the keys and the values, and items()
>>> is just as much part of the Mapping API as keys.
>>>
>>
>> There may be a (small) performance issue with that -- items() requires
>> creating a tuple object for each key/value pair.
>>
>
> it does look like items() is a tad faster (dict with 1000 items), but not
> enough to matter:
>
> In [61]: %timeit {k: d[k] for k in d.keys()}
> 112 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>
> In [62]: %timeit {k: v for k, v in d.items()}
> 92.6 µs ± 1.9 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>

Interesting -- thanks for taking up the challenge. I still suspect that if
we ran the corresponding benchmark at the C level, the first form would
win, but it's a matter of hashing twice vs. creating a tuple -- both of
which have the wazoo optimized out of them so it could go either way. There
are many surprises possible here (e.g. long ago someone found that
`s.startswith('x')` is slower than `s[:1] == 'x'` and the reason is the
name lookup for `startswith`!).


> Anyway, of course it's too late to change. And there are probably other
>> "protocols" that check for the presence of keys and __getitem__(). Also, in
>> a sense keys() is more fundamental -- deriving keys() from items() would be
>> backwards (throwing away the values -- imagine a data type that stores the
>> values on disk).
>>
>
> Does there need to be a single defined "protocol" for a mapping (other
> than the ABC)? -- that is, would **unpacking be able to use .items() and
> keys() be used in other contexts?
>
> And why does ** unpacking need to check at all (LBYL) couldn't it simply
> do something like:
>
> {k: d[k] for k in d}
>
> sure, there could occasionally be a Sequence for which that would happen
> to work (like a range object for instance), but then it would be
> unlikely to result in the expected result anyway -- just like many other
> uses of Duck typing. Or not, and it could still be correct.
>

I don't understand why LBYL is considered such an anti-pattern. It helps
produce much clearer error messages in this case for users who are
exploring this feature, and distinguishing *early* between sequences and
mappings is important for that. Long ago we decided that the distinctive
feature is that mappings have a `keys()` method whereas sequences don't
(and users who add a `keys()` method to a sequence are just asking for
trouble). So that's what we use.

-- 
--Guido van Rossum (python.org/~guido)
*Pronouns: he/him **(why is my pronoun here?)*
<http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________
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/OQOGANKVMEBWTSPMNMOT7ZKCMLAMRBBU/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to