Home > Blockchain >  List of dictionaries - Find count of values
List of dictionaries - Find count of values

Time:07-30

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)

CodePudding user response:

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,
    },
]

CodePudding user response:

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}]

CodePudding user response:

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"])})

CodePudding user response:

Thank You @1extralime, @Peter T. Walker, @AndrejKesely. All 3 of your solutions worked. Thank you so much for prompt responses. How do I give credit to all 3 of you? I clicked up button for all 3 of your solutions. It says I need 15 reputation to cast a vote.

  • Related