Jeb675
Jeb675

Reputation: 45

Compare values in a list of dictionaries and return only dictionaries with highest values

I would like to return a list which contains the dictionary with the highest version number for a given name and given type from dictionaries in a list. I have the following list of dictionaries:

list = [
{
  "name": "name 1",
  "type": "type 1",
  "version": 1,
  }
{ *this one should be returned*
  "name": "name 1",
  "type": "type 1",
  "version": 2,
  }
{
  "name": "name 2",
  "type": "type 1",
  "version": 1,
  }
{ *and this one*
  "name": "name 2",
  "type": "type 1",
  "version": 2,
  }
{
  "name": "name 1",
  "type": "type 2",
  "version": 1,
  }
{ *and this one*
  "name": "name 1",
  "type": "type 2",
  "version": 2,
  }

I would like to be able to return a list just containing the highest version number for a type and a name, so the result for the above would be:

  returned_list = [
{
  "name": "name 1",
  "type": "type 1",
  "version": 2,
  }
{
  "name": "name 2",
  "type": "type 1",
  "version": 2,
  }
{
  "name": "name 1",
  "type": "type 2",
  "version": 2,
  }

I am not sure where to start, any advice would be appreciated.

Upvotes: 1

Views: 48

Answers (3)

John Coleman
John Coleman

Reputation: 52008

Here is an approach which uses a defaultdict to first assemble a dictionary keyed by name,type pairs and whose values are a list of version numbers, which it then assembles into the desired list:

from collections import defaultdict

accumulate = defaultdict(list)
for d in my_list:
    accumulate[(d["name"],d["type"])].append(d["version"])

new_list = [{"name":n,"type":t,"version":max(v)} for (n,t),v in accumulate.items()]

result:

>>> for d in new_list:print(d)

{'name': 'name 1', 'type': 'type 1', 'version': 2}
{'name': 'name 2', 'type': 'type 1', 'version': 2}
{'name': 'name 1', 'type': 'type 2', 'version': 2}

Upvotes: 2

Ehsan
Ehsan

Reputation: 711

lst = []
comp = list_lst[0]['version']
for i in range(len(list_lst)):
    if (list_lst[i]['version']) > comp:
        comp = list_lst[i]['version']
        lst = []
        lst.append(list_lst[i])
    elif (list_lst[i]['version'] == comp):
        lst.append(list_lst[i])

Upvotes: 0

rdas
rdas

Reputation: 21285

Here's one approach

First find the max from the input list. We use max() for this

Then find any & all entries from the original list that may have the same "version". We use filter for this

name_list = [
    {
        "name": "name 1",
        "type": "type 1",
        "version": 1,
    },
    {
        "name": "name 1",
        "type": "type 1",
        "version": 2,
    },
    {
        "name": "name 2",
        "type": "type 1",
        "version": 1,
    },
    {
        "name": "name 2",
        "type": "type 1",
        "version": 2,
    },
    {
        "name": "name 1",
        "type": "type 2",
        "version": 1,
    },
    {
        "name": "name 1",
        "type": "type 2",
        "version": 2,
    }]

max_in_list = max(name_list, key=lambda x: x['version']) # max by version

maxes_in_list = filter(lambda x: x['version'] == max_in_list['version'], name_list) # select if version == max_version

print(list(maxes_in_list))

Output:

[{'name': 'name 1', 'type': 'type 1', 'version': 2}, {'name': 'name 2', 'type': 'type 1', 'version': 2}, {'name': 'name 1', 'type': 'type 2', 'version': 2}]

Upvotes: 1

Related Questions