On Nov 30, 2019, at 13:19, Soni L. <fakedme+py@gmail.com> wrote:
I have a lot of code that looks like this:
def filter(self, it, defs): for x in it: for y in _match_helper(self.key, defs, x[0]): yield (y, x[1])
Try destructuring it: for key, value in it: And now you can use key instead of x[0] and value instead of x[1]. The loop target in a for loop is like a target in an assignment statement, and can do most of the same things. (This doesn’t work for all bindings—you can’t destructure an argument in a parameter list, or from spam import * as first, *rest—but as a first approximation it works anywhere it wouldn’t be confusing, which is usually all you need to remember.)
It'd be quite nice if dict.items() returned a namedtuple so all these x[0], x[1], el[0], el[1], etc would instead be x.key, x.value, el.key, el.value, etc.
I think dict would want to implement it as a C-level structseq (like stat results) instead of a Python-level namedtuple for convenience and performance, but that’s not a big issue. Anyway, I think this would be a good idea. But I’m not sure it’s feasible The problem is that items() is part of a protocol that many types implement, including many third-party types (sortedcontainers.SortedDict, pyrsistent.PMap, pyobjc.NSDictionary, java.collections.Map, whatever the type is for attribute mappings in beautifulsoup, etc., not to mention project-internal types). A whole lot of code is written to work with ,“any mapping”, and all of that code will have to keep using [0] and [1] instead of .key and .value until every mapping type it might be handed has been updated. (That includes the constructors of most of those types, which can handle any object with an items() method just like dict can.) You could get about 75% of the way there pretty easily. This structseq/namedtuple/whatever type could be given a name, and collections.abc.ItemsView could iterate values of that type, so everyone who inherits the items method from the Mapping mixin or builds their own items view that inherits the ItemsView mixin gets the new behavior. Together with types that inherit itend from dict, or delegate it to dict without transforming the results, that covers a lot of mapping types. But it still doesn’t cover all of them. And I don’t think even a future or deprecation schedule would help here. You could document that, starting in 3.12, items must be an 2-item sequence with key and value attributes that are equal to the first and second element instead of just being an sequence with two values. But that’s not something the ABC can test for you, so I don’t think it would have the desired result of pushing the whole ecosystem to change in 4.5 years; people would have to keep using [0] and [1] for many years to come if they wanted to work with all mapping types.