Reputation: 65
I want to search by any character on a list of dicts.
my_list = [
{"name": "MrA", "age": 20, "height": 185},
{"name": "MrsB", "age": 28, "height": 192},
{"name": "MrC", "age": 18, "height": 170},
{"name": "MrD", "age": 50, "height": 177},
{"name": "MrsE", "age": 32, "height": 200},
{"name": "Mrs18F", "age": 21, "height": 175}
]
keywords = "MrA"
my_list = [item for item in my_list if keywords in list(item.values())]
print(my_list) # result is [{"name": "MrA", "age": 20, "height": 185}]
As seen, I can only search by full characters. But I want to handle this list with the expected result is which is search by any character on all fields:
With keywords = "Mrs"
:
[{"name": "MrsB", "age": 28, "height": 192},
{"name": "MrsE", "age": 32, "height": 200},
{"name": "Mrs18F", "age": 21, "height": 175}]
OR keywords = 18
:
[{"name": "MrA", "age": 20, "height": 185},
{"name": "MrC", "age": 18, "height": 170}
{"name": "Mrs18F", "age": 21, "height": 175}]
I don't know How do I make it right. Is there any way I can get the expected result?
Upvotes: 1
Views: 104
Reputation: 24059
You can try this, Some values are int
so you can check with str(query)
and str(value)
.
def fnd_query(lst, query):
res = []
for dct in lst:
for val in dct.values():
if str(query) in str(val):
res.append(dct)
break
return res
print(fnd_query(my_list, 18))
print(fnd_query(my_list, 'Mrs'))
[{'name': 'MrA', 'age': 20, 'height': 185}, {'name': 'MrC', 'age': 18, 'height': 170}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
[{'name': 'MrsB', 'age': 28, 'height': 192}, {'name': 'MrsE', 'age': 32, 'height': 200}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
Upvotes: 1
Reputation: 61920
Use:
my_list = [
{"name": "MrA", "age": 20, "height": 185},
{"name": "MrsB", "age": 28, "height": 192},
{"name": "MrC", "age": 18, "height": 170},
{"name": "MrD", "age": 50, "height": 177},
{"name": "MrsE", "age": 32, "height": 200},
{"name": "Mrs18F", "age": 21, "height": 175}
]
def match_keywords(it, keys):
for val in it.values():
if any(key in str(val) for key in keys):
return True
return False
keywords = ["Mrs", "MrD"]
my_list = [item for item in my_list if match_keywords(item, keywords)]
print(my_list)
Output
[{'name': 'MrsB', 'age': 28, 'height': 192}, {'name': 'MrD', 'age': 50, 'height': 177}, {'name': 'MrsE', 'age': 32, 'height': 200}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
Another example:
keywords = ["18"]
my_list = [item for item in my_list if match_keywords(item, keywords)]
print(my_list)
Output
[{'name': 'MrA', 'age': 20, 'height': 185}, {'name': 'MrC', 'age': 18, 'height': 170}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
This solution allows you to search by different keys across all values of the dictionary.
Upvotes: 5
Reputation: 19432
You want to check if the keyword is in any
of the values of each dictionary. This will be done by converting the keyword to a string, and each of the values:
def find(term, l):
term = str(term)
return [d for d in l if any(term in str(v) for v in d.values())]
print(find("Mrs", my_list))
print(find(18, my_list))
This gives:
[{'name': 'MrsB', 'age': 28, 'height': 192}, {'name': 'MrsE', 'age': 32, 'height': 200}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
[{'name': 'MrA', 'age': 20, 'height': 185}, {'name': 'MrC', 'age': 18, 'height': 170}, {'name': 'Mrs18F', 'age': 21, 'height': 175}]
Upvotes: 3
Reputation: 1509
You can turn the keyword and the values to a string and then check if the value contains the keyword, something like this:
def search_by_value(search_list, keyword):
result = []
keyword = str(keyword)
for l in search_list:
for k, v in l.items():
if keyword in str(v):
result.append(l)
break
return result
my_list = [
{"name": "MrA", "age": 20, "height": 185},
{"name": "MrsB", "age": 28, "height": 192},
{"name": "MrC", "age": 18, "height": 170},
{"name": "MrD", "age": 50, "height": 177},
{"name": "MrsE", "age": 32, "height": 200}
]
print(search_by_value(my_list, "Mrs"))
print(search_by_value(my_list, 18))
Output:
[{'name': 'MrsB', 'age': 28, 'height': 192}, {'name': 'MrsE', 'age': 32, 'height': 200}]
[{'name': 'MrA', 'age': 20, 'height': 185}, {'name': 'MrC', 'age': 18, 'height': 170}]
Upvotes: 1