Python list of dictionaries search

后端 未结 21 2046
-上瘾入骨i
-上瘾入骨i 2020-11-22 09:41

Assume I have this:

[
{\"name\": \"Tom\", \"age\": 10},
{\"name\": \"Mark\", \"age\": 5},
{\"name\": \"Pam\", \"age\": 7}
]

and by searchin

相关标签:
21条回答
  • 2020-11-22 10:15

    Here is a comparison using iterating throuhg list, using filter+lambda or refactoring(if needed or valid to your case) your code to dict of dicts rather than list of dicts

    import time
    
    # Build list of dicts
    list_of_dicts = list()
    for i in range(100000):
        list_of_dicts.append({'id': i, 'name': 'Tom'})
    
    # Build dict of dicts
    dict_of_dicts = dict()
    for i in range(100000):
        dict_of_dicts[i] = {'name': 'Tom'}
    
    
    # Find the one with ID of 99
    
    # 1. iterate through the list
    lod_ts = time.time()
    for elem in list_of_dicts:
        if elem['id'] == 99999:
            break
    lod_tf = time.time()
    lod_td = lod_tf - lod_ts
    
    # 2. Use filter
    f_ts = time.time()
    x = filter(lambda k: k['id'] == 99999, list_of_dicts)
    f_tf = time.time()
    f_td = f_tf- f_ts
    
    # 3. find it in dict of dicts
    dod_ts = time.time()
    x = dict_of_dicts[99999]
    dod_tf = time.time()
    dod_td = dod_tf - dod_ts
    
    
    print 'List of Dictionries took: %s' % lod_td
    print 'Using filter took: %s' % f_td
    print 'Dict of Dicts took: %s' % dod_td
    

    And the output is this:

    List of Dictionries took: 0.0099310874939
    Using filter took: 0.0121960639954
    Dict of Dicts took: 4.05311584473e-06
    

    Conclusion: Clearly having a dictionary of dicts is the most efficient way to be able to search in those cases, where you know say you will be searching by id's only. interestingly using filter is the slowest solution.

    0 讨论(0)
  • 2020-11-22 10:20

    I found this thread when I was searching for an answer to the same question. While I realize that it's a late answer, I thought I'd contribute it in case it's useful to anyone else:

    def find_dict_in_list(dicts, default=None, **kwargs):
        """Find first matching :obj:`dict` in :obj:`list`.
    
        :param list dicts: List of dictionaries.
        :param dict default: Optional. Default dictionary to return.
            Defaults to `None`.
        :param **kwargs: `key=value` pairs to match in :obj:`dict`.
    
        :returns: First matching :obj:`dict` from `dicts`.
        :rtype: dict
    
        """
    
        rval = default
        for d in dicts:
            is_found = False
    
            # Search for keys in dict.
            for k, v in kwargs.items():
                if d.get(k, None) == v:
                    is_found = True
    
                else:
                    is_found = False
                    break
    
            if is_found:
                rval = d
                break
    
        return rval
    
    
    if __name__ == '__main__':
        # Tests
        dicts = []
        keys = 'spam eggs shrubbery knight'.split()
    
        start = 0
        for _ in range(4):
            dct = {k: v for k, v in zip(keys, range(start, start+4))}
            dicts.append(dct)
            start += 4
    
        # Find each dict based on 'spam' key only.  
        for x in range(len(dicts)):
            spam = x*4
            assert find_dict_in_list(dicts, spam=spam) == dicts[x]
    
        # Find each dict based on 'spam' and 'shrubbery' keys.
        for x in range(len(dicts)):
            spam = x*4
            assert find_dict_in_list(dicts, spam=spam, shrubbery=spam+2) == dicts[x]
    
        # Search for one correct key, one incorrect key:
        for x in range(len(dicts)):
            spam = x*4
            assert find_dict_in_list(dicts, spam=spam, shrubbery=spam+1) is None
    
        # Search for non-existent dict.
        for x in range(len(dicts)):
            spam = x+100
            assert find_dict_in_list(dicts, spam=spam) is None
    
    0 讨论(0)
  • 2020-11-22 10:23
    people = [
    {'name': "Tom", 'age': 10},
    {'name': "Mark", 'age': 5},
    {'name': "Pam", 'age': 7}
    ]
    
    def search(name):
        for p in people:
            if p['name'] == name:
                return p
    
    search("Pam")
    
    0 讨论(0)
提交回复
热议问题