On Sun, Dec 27, 2020 at 1:15 PM Brendan Barnwell <brenb...@brenbarn.net> wrote:
>
> On 2020-12-26 18:03, Chris Angelico wrote:
> > On Sun, Dec 27, 2020 at 11:36 AM Greg Ewing <greg.ew...@canterbury.ac.nz> 
> > wrote:
> >>
> >> On 27/12/20 10:15 am, Christopher Barker wrote:
> >> > It does seem like ** could be usable with any iterable that returns
> >> > pairs of objects. However the trick is that when you iterate a dict, you
> >> > get the keys, not the items, which makes me think that the only thing
> >> > you should *need* is an items() method that returns an iterable (pf
> >> > pairs of objects).
> >>
> >> It seems to me it would be more fundamental to use iteration to get
> >> the keys and indexing to get the corresponding values. You're only
> >> relying on dunder methods then.
> >>
> >
> > But that would mean that a lot of iterables would look like mappings
> > when they're not. Consider:
> >
> >>>> def naive_items(x):
> > ...     return [(key, x[key]) for key in x]
> > ...
> >>>> naive_items(range(9, -1, -1))
> > [(9, 0), (8, 1), (7, 2), (6, 3), (5, 4), (4, 5), (3, 6), (2, 7), (1, 8), 
> > (0, 9)]
>
>         I don't see that as a major problem.  It is no more "surprising" than
> doing something like list('abc') and getting ['a', 'b', 'c'].  If you do
> {**range(9, -1, -1)} you may get a result that looks strange or isn't
> useful, but as long as the result is consistent with the protocol,
> that's fine.  Just don't use **-unpacking with ranges if you don't want to.
>

Perhaps, but that means you can't raise TypeError for anything
iterable. Instead, you'd have to raise ValueError, because it could
potentially be valid. Are mappings really just iterables with indexing
(which most iterables support), or are they distinctly different?
Remember, most things iterate over their *values*, but a dict iterates
over its *keys*.

On the plus side, you COULD convert some objects into sparse lists by
basically just dictifying them:

>>> {**range(5)} # with this proposal
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}

But on the downside, you could only do this if they iterate the 'right
way', which most iterables won't. It would be MUCH more useful if
there were a dedicated way to request the valid keys or items, and use
that instead. Then you could convert *any* iterable that way.

At the moment, you can create an actual dict from any iterable by
enumerating, and that will give the correct items:

>>> def smarter_items(x):
...     return list(dict(enumerate(x)).items())
...
>>> smarter_items(range(9, -1, -1))
[(0, 9), (1, 8), (2, 7), (3, 6), (4, 5), (5, 4), (6, 3), (7, 2), (8, 1), (9, 0)]
>>> smarter_items(range(10, 20))
[(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7,
17), (8, 18), (9, 19)]

If you want to dictify something, that'd be the more normal way to do
it, IMO. Instead of something with lots of false positives, wouldn't
it be cleaner to have a protocol that specifically returns the
equivalent of dict.items()?

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/S24DU6DYBNFHMWIIDQU23YW5MI5OUU7U/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to