List of dictionaries – Find count of values

Question:

I am having difficulty to implement this logic.

Here is the input, list of dictionaries

list = [ 
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent1", "env": "dev"},
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent2", "env": "uat"},
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent3", "env": "prod"},
    {"mne": "ABC", "appname": "abc2", "agentname": "abcagent4", "env": "dev"},
    {"mne": "ABC", "appname": "abc2", "agentname": "abcagent5", "env": "prod"},
    {"mne": "XYZ", "appname": "asf1", "agentname": "asfagent1", "env": "dev"},
    {"mne": "XYZ", "appname": "asf2", "agentname": "asfagent2", "env": "prod"},
]

Here is the output, I am looking for:

[
    {"mne": "ABC", "non_prod_app_count": 2, "prod_app_count": 2, "non_prod_agent_count": 3, "prod_agent_count": 2},
    {"mne": "XYZ", "non_prod_app_count": 1, "prod_app_count": 1, "non_prod_agent_count": 1, "prod_agent_count": 1}
]

Explanation:

non_prod (dev, uat)
prod (prod)

For the first dictionary in the output, here is the explanation.

non_prod_app_count = 2 (abc1, abc2)
prod_app_count = 2 (abc1, abc2)
non_prod_agent_count = 3 (abcagent1, abcagent2, abcagent4)
prod_agent_count = 2 (abcagent3, abcagent5)
Asked By: gvk

||

Answers:

You should not use ‘list’ as your variable name.
Pandas is a tool that can help here. Its bulky but should get the job done.

import pandas as pd
data = [ 
{"mne": "ABC", "appname": "abc1", "agentname": "abcagent1", "env": "dev"},
{"mne": "ABC", "appname": "abc1", "agentname": "abcagent2", "env": "uat"},
{"mne": "ABC", "appname": "abc1", "agentname": "abcagent3", "env": "prod"},
{"mne": "ABC", "appname": "abc2", "agentname": "abcagent4", "env": "dev"},
{"mne": "ABC", "appname": "abc2", "agentname": "abcagent5", "env": "prod"},
{"mne": "XYZ", "appname": "asf1", "agentname": "asfagent1", "env": "dev"},
{"mne": "XYZ", "appname": "asf2", "agentname": "asfagent2", "env": "prod"},
]

df = pd.DataFrame(data)
rows = []
for mne in df.mne.unique():
    tmp_df = df[df['mne']==mne]
    rows.append({
        'mne':mne,
        'non_prod_app_count': len(tmp_df[tmp_df['env']!= 'prod']['appname'].unique()),
        'prod_app_count':len(tmp_df[tmp_df['env']=='prod']['appname'].unique()),
        'non_prod_agent_count':len(tmp_df[tmp_df['env'].isin(['uat','dev'])]['agentname'].unique()),
        'prod_agent_count':len(tmp_df[tmp_df['env']=='prod']['agentname'].unique()),
    })

print(rows)

output:

[{'mne': 'ABC',
  'non_prod_app_count': 2,
  'prod_app_count': 2,
  'non_prod_agent_count': 3,
  'prod_agent_count': 2},
 {'mne': 'XYZ',
  'non_prod_app_count': 1,
  'prod_app_count': 1,
  'non_prod_agent_count': 1,
  'prod_agent_count': 1}]
Answered By: 1extralime

Try:

lst = [
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent1", "env": "dev"},
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent2", "env": "uat"},
    {"mne": "ABC", "appname": "abc1", "agentname": "abcagent3", "env": "prod"},
    {"mne": "ABC", "appname": "abc2", "agentname": "abcagent4", "env": "dev"},
    {"mne": "ABC", "appname": "abc2", "agentname": "abcagent5", "env": "prod"},
    {"mne": "XYZ", "appname": "asf1", "agentname": "asfagent1", "env": "dev"},
    {"mne": "XYZ", "appname": "asf2", "agentname": "asfagent2", "env": "prod"},
]

mne = {}
for d in lst:
    mne.setdefault(d["mne"], []).append(d)

out = []
for k, v in mne.items():

    env = {}
    for d in v:
        env.setdefault(d["env"], []).append(d)

    non_prod_app_count = set(
        i["appname"] for k, v in env.items() for i in v if k != "prod"
    )

    prod_app_count = set(v["appname"] for v in env["prod"])

    non_prod_agent_count = set(
        i["agentname"] for k, v in env.items() for i in v if k != "prod"
    )

    prod_agent_count = set(v["agentname"] for v in env["prod"])

    out.append(
        dict(
            mne=k,
            non_prod_app_count=len(non_prod_app_count),
            prod_app_count=len(prod_app_count),
            non_prod_agent_count=len(non_prod_agent_count),
            prod_agent_count=len(prod_agent_count),
        )
    )

print(out)

Prints:

[
    {
        "mne": "ABC",
        "non_prod_app_count": 2,
        "prod_app_count": 2,
        "non_prod_agent_count": 3,
        "prod_agent_count": 2,
    },
    {
        "mne": "XYZ",
        "non_prod_app_count": 1,
        "prod_app_count": 1,
        "non_prod_agent_count": 1,
        "prod_agent_count": 1,
    },
]
Answered By: Andrej Kesely

First, you iterate the list of dictionaries and create a corresponding dictionary to store the different apps and agents.

Then, you iterate the entries and put the different names into their corresponding list.

Last, you count the length of the lists you’ve created

apps = {}

for l in list:
  app = l["mne"]
  if app not in apps.keys():
    apps[app] = {"mne": l["mne"],
                "non_prod_app": [], 
                "prod_app": [], 
                "non_prod_agent": [], 
                "prod_agent": []}
for l in list:
  app = l["mne"]
  if l["env"] == "prod":
    if l["appname"] not in apps[app]["prod_app"]:
        apps[app]["prod_app"].append(l["appname"])
    if l["agentname"] not in apps[app]["prod_agent"]:
        apps[app]["prod_agent"].append(l["agentname"])
  else:
    if l["appname"] not in apps[app]["non_prod_app"]:
        apps[app]["non_prod_app"].append(l["appname"])
    if l["agentname"] not in apps[app]["non_prod_agent"]:
        apps[app]["non_prod_agent"].append(l["agentname"])

returnList = []     
for l in apps.values():
    returnList.append({"mne": l["mne"],
                "non_prod_app": len(l["non_prod_app"]), 
                "prod_app": len(l["prod_app"]), 
                "non_prod_agent": len(l["non_prod_agent"]), 
                "prod_agent": len(l["prod_agent"])})
Answered By: Peter T. Walker
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.