On Dec 5, 2019, at 13:43, Juancarlo Añez <apal...@gmail.com> wrote:
> 
> 
> I just found this code:
> 
> def get_product_item(jsonld_items):
>     for item in jsonld_items:
>         if item['@type'] == 'Product':
>             return item
>     else:
>         return {}
> 
> My argument is that the intent is clearer in:
> 
> def get_product_item(jsonld_items):
>     return first((item for item in jsonld_items if item['@type'] == 
> 'Product'), {})

There’s already a first_true in the recipes that does the filtering and 
firsting together.

Of course there’s the usual issue about filter vs. genexpr when your predicate 
is naturally an in-line expression rather than a function, but otherwise:

    from more_itertools import first_true

    def get_product_item(jsonId_items):
        return first_true(jsonId_items, lambda item: item['@type'] == 
'Product', {})

Or even:

    get_product_item = partial(first_true, pred=lambda item: item['@type'] == 
'Product', default={})

I think in this case, because of the expression-vs.-lambda issue, I’d write it 
with first and a genexpr if we had both. But a lot of itertoolsy code is full 
of lambdas and partials like this (to call filter and map, use as groupby and 
unique keys, etc.), and often the condition is something you’ve already wrapped 
up as a function in the first place, so I’m not sure how generally that applies 
without more examples.

> As a reminder, first()'s definition in Python is:
> 
> def first(seq, default=None):
>     return next(iter(seq), default=default)
> 
> It could be optimized (implemented in C) if it makes it into the stdlib.

I don’t think it needs to be optimized. Most itertoolsy things that can be 
built by composing existing functions (like most of the recipes) are fast 
enough in Python; it’s the stuff that needs to loop and yield (like most of the 
stuff actually in the module) that gets a major improvement in C. It’s worth 
measuring rather than guessing, but my guess would be that the same applies 
here.

The only problem is that right now, the entire module is in C, so anything 
that’s not optimized has to be a recipe and vice-versa. I’m pretty sure the 
idea of splitting itertools into a Python module with a C accelerator (like a 
lot of other modules in the stdlib) has come up before, but either there’s 
never a good enough use case, or just nobody volunteers to do it. And first 
might well be the candidate that’s worth it.

Then again, maybe it is worth optimizing. Or maybe it’s fine to just list it as 
a recipe (the recipes docs already link to more_itertools, which already has 
it).
_______________________________________________
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/EEONODVROFGOL6AE3D7F772OHZYASRZN/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to