Alain Skyter
Alain Skyter

Reputation: 65

Search by any character on a list of dict with Python

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

Answers (4)

I'mahdi
I'mahdi

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

Dani Mesejo
Dani Mesejo

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

Tomerikoo
Tomerikoo

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

noah1400
noah1400

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

Related Questions