> The temptation to insist "see, YAGNI!" at this point I shall resist.
*You* might not need it, but I've seen it come up a lot on Stack Overflow, and all too often people end up going for the much less efficient solution. I personally have also written code with practical applications using `next(iter(mydict))`. > I was +0 sympathetic to that until you posted this obvious extension > of the idea I don't see these dict methods as an "obvious extension" of the idea; I see them as unneeded/irrelevant *if* a more general way of doing this is added to itertools. > That's an awful lot of new methods to take advantage of what for many > applications of dict (in fact, *all* of my applications ever[1]) is an > irrelevant ordering. I agree that it's a lot of methods to add. That's precisely why I prefer Inada Naoki's suggestion of additions to itertools, and why I've never bothered starting a thread on the subject myself. But since the topic was being discussed after Erik started this thread, I thought I might mention the alternative solution that's been in the back of my head for a while. > [A]nyone who wants it can do it themselves: As I said in my previous message, the existing idiom (`next(iter(mydict))`) appears to be extremely non-obvious for beginners in Python, causing them to often go for much more inefficient options. No one is claiming "there is no way to do this" at present; the argument is that the best way to do this is, at present, *not sufficiently obvious*. > These defs do something undefined on unordered mappings (ie, not based > on dict), and may be dangerous in that sense. Excellent point (though note that my suggestion was to extend the dict interface, not the interface for all mappings). > In the current implementation, positional indexing is time-expensive Yes, that's exactly why I don't support Erik's original suggestion of positional indexing for dict.keys(), dict.values() and dict.items(), and why I *only* support easy ways of fetching the first/last object from the view. > I wonder if any code is being written obscurely to ensure that > keys get added to dicts in the "right" order I personally have used dictionaries as ordered sets in the past (skip to the last code snippet in this answer: https://codereview.stackexchange.com/a/264437/24517), and would object to this being called an "obscure" use of the data structure. It is, by now, both well-known and well-advertised in the documentation that dictionaries are guaranteed to maintain insertion order. It's obviously not how the data structure has historically been used, but I don't see how that makes it an invalid use of the data structure *now*. Why shouldn't users be expected to exploit an advertised feature of the language? > On 6 Oct 2021, at 10:29, Stephen J. Turnbull <stephenjturnb...@gmail.com> > wrote: > > Alex Waygood writes: > >> Whereas obviously, > > The temptation to insist "see, YAGNI!" at this point I shall resist. > >> a much better way (especially if it's a very large dictionary) is >> to do: >> first_key = next(iter(mydict)) > >> [Inada Naoki] >>> I think we can add `itertools.first()` for this idiom, and >>> `itertools.last()` for `next(iter(reversed(x)))` idiom. > > I was +0 sympathetic to that until you posted this obvious extension > of the idea: > >> I like this idea, a lot. Another possibility I've been wondering >> about was whether several methods should be added to the dict >> interface: >> dict.first_key = lambda self: next(iter(self)) >> dict.first_val = lambda self: next(iter(self.values())) >> dict.first_item = lambda self: next(iter(self.items())) >> dict.last_key = lambda self: next(reversed(self)) >> dict.last_val = lambda self: next(reversed(self.values())) >> dict.last_item = lambda self: next(reversed(self.items())) > > That's an awful lot of new methods to take advantage of what for many > applications of dict (in fact, *all* of my applications ever[1]) is an > irrelevant ordering. > > And anyone who wants it can do it themselves: > > def first_key(dct): return next(iter(dct)) > def first_val(dct): return next(iter(dct.values())) > def first_item(dct): return next(iter(dct.items())) > def last_key(dct): return next(reversed(iter(dct))) > def last_val(dct): return next(reversed(iter(dct.values()))) > def last_item(dct): return next(reversed(iter(dct.items()))) > > These defs do something undefined on unordered mappings (ie, not based > on dict), and may be dangerous in that sense. OTOH, I suspect the > methods will do the wrong thing with many ordered mappings based on > dict that support orders other than insertion order. > >> But I think I like a lot more the idea of adding general ways of >> doing these things to itertools. > > If you want to convince others, you really need to be more specific > about the requirements that lead you to this conclusion. In the > current implementation, positional indexing is time-expensive, much > more so than keeping an auxiliary list and using dct[lst[ndx]]. It > could also allow timing attacks if used in security-sensitive code. > And I wonder if any code is being written obscurely to ensure that > keys get added to dicts in the "right" order, instead of keeping an > explict, efficient, and reorderable auxiliary list of keys? > > Footnotes: > [1] It's true that some code I import is probably improved because > the developers don't waste time tracking down test failures in dict- > based data structures. :-)
_______________________________________________ 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/GPPMS36S6XCN63ZIF64FLG7UQHFDXO5F/ Code of Conduct: http://python.org/psf/codeofconduct/