Creating dictionary with list as values

Question:

I have a bind file in below format

BIND REQ conn=8349228 op=0 msgID=1 version=3 type=SIMPLE dn="uid=test1,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349229 op=0 msgID=1 version=3 type=SIMPLE dn="uid=test1,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349230 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349231 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349232 op=0 msgID=1 version=3 type=SIMPLE dn="uid=COVESEOS,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349233 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349235 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349234 op=0 msgID=1 version=3 type=SIMPLE dn="uid=COVESEOS,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349236 op=0 msgID=1 version=3 type=SIMPLE dn="uid=COVESEOS,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349237 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349238 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349239 op=0 msgID=1 version=3 type=SIMPLE dn="uid=COVESEOS,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349240 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349241 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"
BIND REQ conn=8349242 op=0 msgID=1 version=3 type=SIMPLE dn="uid=xdev,ou=Users,ou=Internal,o=example"`

Now what I am trying to do is create a dictionary of the format {'uid' : [connections ids]}, for example like below

{'test1' : [8349228,8349229,...],
 'xdev' : [8349230,8349231,...],
 ...so on  }`

What can I try to resolve this?

Asked By: Rohit

||

Answers:

This method should do it. When you read the file, call this method and it will return a dict in the format you specified.

import re
def input_to_dict(inp):  # inp = input from text file
    for line in inp.split("n"):
        pattern = re.compile("uid=([A-Za-z0-9]{1,}),")
        id_pattern = re.compile("conn=([0-9]{1,})")
        name = pattern.search(line).group(1)
        c_id =id_pattern.search(line).group(1)
        if name in d.keys():
            d[name].append(c_id)
        else:
            d[name] = [c_id]
    return d

Example usage:

with open("file.txt", "r") as file:
    lines = file.readlines()
    d = input_to_dict(lines)
Answered By: Jake Conway

These would be the steps:

Create empty dictionary 
Loop through lines in input file 
    Find values of `uid` and `conn` (easiest way using regex)
    Check if current `uid` exists in dictionary 
        It doesn't, create new entry with current `uid` as key and empty list as value.
    Append `conn` to list associated to `uid` key

Add key&value to dict

For adding keys & values to dict, You should use:

if somekey not in dict1.keys():
    dict1[somekey] = []
dict1[somekey].append(somevalue)

You shouldn’t use any “external” lists, just ones created inside dictionary.

Answered By: Fejs

As comments suggested you can use defaultdict with list default value. Then just run regular expression for each line in file and capture uid & connection id to two groups which are added to result:

import re
from collections import defaultdict

res = defaultdict(list)
with open('log.txt') as f:
    for line in f:
        m = re.search('conn=([w]*).*uid=([^,]*)', line)
        conn_id, uid = m.group(1, 2)
        res[uid].append(conn_id)

print(res)

Output:

defaultdict(<type 'list'>, {
   'test1': ['8349228', '8349229'], 
   'xdev': ['8349230', '8349231', '8349233', '8349235', '8349237', '8349238', '8349240', '8349241', '8349242'], 
   'COVESEOS': ['8349232', '8349234', '8349236', '8349239']
})
Answered By: niemmi
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.