766π
next((x for x in test_list if x.value == value), None)
This gets the first item from the list that matches the condition, and returns None
if no item matches. Itβs my preferred single-expression form.
However,
for x in test_list:
if x.value == value:
print("i found it!")
break
The naive loop-break version, is perfectly Pythonic β itβs concise, clear, and efficient. To make it match the behavior of the one-liner:
for x in test_list:
if x.value == value:
print("i found it!")
break
else:
x = None
This will assign None
to x
if you donβt break
out of the loop.
39π
Since it has not been mentioned just for completion.
The good olβ filter to filter your to be filtered elements.
Functional programming ftw.
####### Set Up #######
class X:
def __init__(self, val):
self.val = val
elem = 5
my_unfiltered_list = [X(1), X(2), X(3), X(4), X(5), X(5), X(6)]
####### Set Up #######
### Filter one liner ### filter(lambda x: condition(x), some_list)
my_filter_iter = filter(lambda x: x.val == elem, my_unfiltered_list)
### Returns a flippin' iterator at least in Python 3.5 and that's what I'm on
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
### [1, 2, 3, 4, 5, 5, 6] Will Return: ###
# 5
# 5
# Traceback (most recent call last):
# File "C:\Users\mousavin\workspace\Scripts\test.py", line 22, in <module>
# print(next(my_filter_iter).value)
# StopIteration
# You can do that None stuff or whatever at this point, if you don't like exceptions.
I know that generally in python list comprehensions are preferred or at least
that is what I read, but I donβt see the issue to be honest. Of course Python is not an FP language, but Map / Reduce / Filter are perfectly readable and are the most standard of standard use cases in functional programming.
So there you go. Know thy functional programming.
filter condition list
It wonβt get any easier than this:
next(filter(lambda x: x.val == value, my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions
- [Django]-Django index page best/most common practice
- [Django]-Django queryset filter β Q() | VS __in
- [Django]-Django-Forms with json fields
39π
A simple example:
We have the following array
li = [{"id":1,"name":"ronaldo"},{"id":2,"name":"messi"}]
Now, we want to find the object in the array that has id equal to 1
- Use method
next
with list comprehension
next(x for x in li if x["id"] == 1 )
- Use list comprehension and return first item
[x for x in li if x["id"] == 1 ][0]
- Custom Function
def find(arr , id):
for x in arr:
if x["id"] == id:
return x
find(li , 1)
Output all the above methods is {'id': 1, 'name': 'ronaldo'}
- [Django]-Paginating the results of a Django forms POST request
- [Django]-The QuerySet value for an exact lookup must be limited to one result using slicing. Filter error
- [Django]-Django Model() vs Model.objects.create()
4π
Old question but I use this quite frequently (for version 3.8). Itβs a bit of syntactic salt, but it has the advantage over the top answer in that you could retrieve a list of results (if there are multiple) by simply removing the [0]
and it still defaults to None
if nothing is found. For any other condition, simply change the x.value==value
to what ever youβre looking for.
_[0] if (_:=[x for x in test_list if x.value==value]) else None
- [Django]-Django dynamic forms β on-the-fly field population?
- [Django]-Django return file over HttpResponse β file is not served correctly
- [Django]-Handling race condition in model.save()
3π
You could do something like this
dict = [{
"id": 1,
"name": "Doom Hammer"
},
{
"id": 2,
"name": "Rings ov Saturn"
}
]
for x in dict:
if x["id"] == 2:
print(x["name"])
Thats what i use to find the objects in a long array of objects.
- [Django]-How to manually assign imagefield in Django
- [Django]-ModuleNotFoundError: No module named 'grp' on windows
- [Django]-How to define two fields "unique" as couple
2π
You could also implement rich comparison via __eq__
method for your Test
class and use in
operator.
Not sure if this is the best stand-alone way, but in case if you need to compare Test
instances based on value
somewhere else, this could be useful.
class Test:
def __init__(self, value):
self.value = value
def __eq__(self, other):
"""To implement 'in' operator"""
# Comparing with int (assuming "value" is int)
if isinstance(other, int):
return self.value == other
# Comparing with another Test object
elif isinstance(other, Test):
return self.value == other.value
import random
value = 5
test_list = [Test(random.randint(0,100)) for x in range(1000)]
if value in test_list:
print "i found it"
- [Django]-Django substr / substring in templates
- [Django]-Django Model() vs Model.objects.create()
- [Django]-Django models: mutual references between two classes and impossibility to use forward declaration in python
1π
I just ran into a similar problem and devised a small optimization for the case where no object in the list meets the requirement.(for my use-case this resulted in major performance improvement):
Along with the list test_list, I keep an additional set test_value_set which consists of values of the list that I need to filter on. So here the else part of agfβs solution becomes very-fast.
- [Django]-How to make two django projects share the same database
- [Django]-How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?
- [Django]-Duplicate column name
0π
For below code, xGen is an anonomous generator expression, yFilt is a filter object. Note that for xGen the additional None parameter is returned rather than throwing StopIteration when the list is exhausted.
arr =((10,0), (11,1), (12,2), (13,2), (14,3))
value = 2
xGen = (x for x in arr if x[1] == value)
yFilt = filter(lambda x: x[1] == value, arr)
print(type(xGen))
print(type(yFilt))
for i in range(1,4):
print('xGen: pass=',i,' result=',next(xGen,None))
print('yFilt: pass=',i,' result=',next(yFilt))
Output:
<class 'generator'>
<class 'filter'>
xGen: pass= 1 result= (12, 2)
yFilt: pass= 1 result= (12, 2)
xGen: pass= 2 result= (13, 2)
yFilt: pass= 2 result= (13, 2)
xGen: pass= 3 result= None
Traceback (most recent call last):
File "test.py", line 12, in <module>
print('yFilt: pass=',i,' result=',next(yFilt))
StopIteration
- [Django]-Django manage.py runserver invalid syntax
- [Django]-Django Form File Field disappears on form error
- [Django]-Django connection to postgres by docker-compose
0π
If you are looking for an object in an array in Python. You can use the if conditional.
model_t1 = [0,1,2,3,4]
model_t2 = [7,8,9,15,14]
_data = model_t1
for md in model_t2:
_data.append(md)
for p_data in _data:
if len(p_data['Property']) == 'Value':
print(json(p_data))
- [Django]-Exclude fields in Django admin for users other than superuser
- [Django]-Django: Implementing a Form within a generic DetailView
- [Django]-How can I get MINIO access and secret key?
0π
Many great answers already, all dealing with single item lookup, as requested by the OP.
However, if you need to look up multiple items from the list
, and your lookup values are unique, e.g. unique ids, it could pay off considerably to convert the list
to a dict
.
For example:
# dummy data
my_items = [{'id': i, ...} for i in range(1000)]
# convert to dict
my_items_dict = {item['id']: item for item in my_list}
# lookup multiple items
for item_id in long_list_of_ids:
item = my_items_dict.get(item_id)
...
- [Django]-Django models: Only permit one entry in a model?
- [Django]-Disable session creation in Django
- [Django]-Change a field in a Django REST Framework ModelSerializer based on the request type?