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/