gvk
gvk

Reputation: 15

List of dictionaries - Find count of values

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)

Upvotes: 1

Views: 87

Answers (3)

Peter T. Walker
Peter T. Walker

Reputation: 332

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

Upvotes: 0

Andrej Kesely
Andrej Kesely

Reputation: 195613

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

Upvotes: 1

1extralime
1extralime

Reputation: 626

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

Upvotes: 1

Related Questions