4

我有一个字典列表。我正在尝试对所述字典值进行“模糊”搜索并返回完整的字典。

因此,如果我有一个如下的字典列表:

[
{"Name":"Arnold", "Age":"52", "Height":"160"}, 
{"Name":"Donald", "Age":"52", "Height":"161"}, 
{"Name":"Trevor", "Age":"22", "Height":"150"}
]

“ nol ”的搜索词应该返回

{"Name":"Arnold", "Age":"52", "Height":"160"} 

虽然“ 52 ”的搜索词应返回:

{"Name":"Arnold", "Age":"52", "Height":"160"} 
{"Name":"Donald", "Age":"52", "Height":"161"}

我知道我可以使用 iteritems 在特定键处搜索值,我只是不清楚如何在字典中搜索所有键/值(不知道键名),然后在匹配时返回所述字典在任何。这在python中可能吗?

4

3 回答 3

4

你可以使用类似的东西

>>> l = [
... {"Name":"Arnold", "Age":"52", "Height":"160"}, 
... {"Name":"Donald", "Age":"52", "Height":"161"}, 
... {"Name":"Trevor", "Age":"22", "Height":"150"}
... ]
>>>
>>> [d for d in l if any("nol" in v for v in d.values())]
[{'Age': '52', 'Name': 'Arnold', 'Height': '160'}]
>>>
>>> [d for d in l if any("52" in v for v in d.values())]
[{'Age': '52', 'Name': 'Arnold', 'Height': '160'}, {'Age': '52', 'Name': 'Donald', 'Height': '161'}]
于 2013-08-20T14:58:52.720 回答
2

这是我的版本,它不会将所有结果同时保存在一个列表中,而是根据需要生成它们。

import itertools

database = [
    {"Name":"Arnold", "Age":"52", "Height":"160"}, 
    {"Name":"Donald", "Age":"52", "Height":"161"}, 
    {"Name":"Trevor", "Age":"22", "Height":"150"},
]

def search(s):
    s = s.lower() # it is a nice feature to ignore case
    for item in database:
        if any(s in v.lower() for v in item.values()): # if any value contains s
            yield item # spit out the item — this is a generator function

# iterate over at most 5 first results
for result in itertools.islice(search("52"), 5):   
    print(result)
{'Height': '160', 'Age': '52', 'Name': 'Arnold'}
{'Height': '161', 'Age': '52', 'Name': 'Donald'}
于 2013-08-20T16:25:11.260 回答
1

另一个略有不同的选择:

searchTerm = "nol"
unusedCharacter = "\n"  # This should be a character that will never appear in your search string.
# Changed this to a generator to avoid searching the whole dict all at once:
results = (d for d in l if searchTerm in unusedCharacter.join(d.values()))

# Produce a limited number of results:
limitedResults = []
maxResults = 5
for k, result in enumerate(results):
    if k == maxResults:
        break
    limitedResults.append(result)
于 2013-08-20T15:28:09.600 回答