I have encountered plenty of uses for first(), usually the argument is a
list or even a dict or set that’s already computed — for sets, it’s common
that it’s known there’s only one element, the question is how to get that
element.

On Thu, Dec 5, 2019 at 14:28 Andrew Barnert via Python-ideas <
python-ideas@python.org> wrote:

> 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/
>
-- 
--Guido (mobile)
_______________________________________________
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/WYGECCEPYBYJF5ALJTMMVKT45FZIB2IG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to