Still - the "filter" call is almost as simple as it can get for a generic
enough way to do what you are requesting.
There is some boiler plate needed around it if you want an actual eager
result or a default value, if no match is found, that is true - but still,
given a list like



On Sat, May 7, 2022 at 1:51 PM Paul Moore <p.f.mo...@gmail.com> wrote:

> On Sat, 7 May 2022 at 16:42, <python-id...@lucas.rs> wrote:
> >
> > In its current implementation, the list type does not provide a simple
> and straightforward way to retrieve one of its elements that fits a certain
> criteria.
> >
> > If you had to get the user where user['id'] == 2 from this list of
> users, for example, how would you do it?
> >
> > users = [
> >     {'id': 1,'name': 'john'},
> >     {'id': 2, 'name': 'anna'},
> >     {'id': 3, 'name': 'bruce'},
> > ]
> >
> > # way too verbose and not pythonic
> > ids = [user['id'] for user in users]
> > index = ids.index(2)
> > user_2 = users[index]
>

user_2 = next(filter(lambda record: record["id"] == 2, users), default_val)


Or otherwise, use some library to have some higher level options to
manipulate
your data structures, even if they are lists of dictionaries.

I am right now working on "rows" (github: turicas/rows) package and charged
with
creating possibilities of lazy querying the data structures. This is
currently working
on my development branch:
In [26]: import rows

In [27]: zz =rows.table.FlexibleTable()

In [28]: zz.extend(users)

In [29]: zz
Out[29]: <rows.Table 2 fields, 3 rows>

In [30]: zz.filter = "id = 2"

In [31]: zz
Out[31]: <rows.Table 2 fields, 1 rows>

In [32]: zz[0]
Out[32]: Row(id=2, name='anna')

(or, if you want dicts back, you have to configure the Table instance:

In [33]: zz.row_class = dict

In [34]: zz[0]
Out[34]: {'id': 2, 'name': 'anna'}
)

https://github.com/turicas/rows/tree/feature/queries



> >
> > # short, but it feels a bit janky
> > user_2 = next((user for user in users if user['id'] == 2), None)
> >
> > # this is okay-ish, i guess
> > users_dict = {user['id']: user for user in users}
> > user_2 = users_dict.get(2)
> >
> >
> > In my opinion, the list type could have something along these lines:
> >
> > class MyList(list):
> >     def find(self, func, default=None):
> >         for i in self:
> >             if func(i):
> >                 return i
> >         return default
> >
> > my_list = MyList(users)
> > user_2 = my_list.find(lambda user: user['id'] == 2)
> > print(user_2)  # {'id': 2, 'name': 'anna'}
>
> You seem to want a function, but it's not obvious to me why you need that.
>
> found = None
> for user in users:
>     if user["id"] == 2:
>         found = user
>         break
>
> seems fine to me. If you need a function
>
> def find_user(id):
>     for user in users:
>         if user["id"] == id:
>             return user
>
> works fine.
>
> Python is very much a procedural language, and "simple and
> straightforward" often equates to a few statements, or a loop, or
> similar. Unlike functional languages, where people tend to think of
> "simple" code as being about combining basic functions into compound
> expressions that do "clever stuff", Python code tends to be viewed as
> "simple and straightforward" (or "Pythonic" if you like) if it
> *doesn't* try to combine too much into one expression, but describes
> what you're doing in a step by step manner.
>
> So yes, a list doesn't provide the sort of "find" method you're
> suggesting. That's because a loop is easy, and does the job just fine.
>
> Paul
> _______________________________________________
> 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/IIO2LDWQ7L3N2SJYV6SFJQ5KHMKWSFNU/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
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/5NJGVVEUJXWUMNYZPJTZJAQCT4QKW5H3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to