UserYmY
UserYmY

Reputation: 8554

How can I create a dictionary within another dictionary with count capability?

I have a set of files, in which I want to extract special names and count the name in each file. I want my final result to be two dictionaries like below:

{ID1:{sam:1,maj:5, tif:7, paul:1},ID2={maj=4,bib=5},..}

I wrote the below code for that:

val={}   
for m in result:    
    f= open(path+m[1]+'.txt', 'r')
    for line in f:
        search_str= "my_name"
        if line.startswith(search_str):            
            linename = line.split(' ',2)[1].strip()
            key= get_name_part(linename)                       
            val[key] = val.get(key, 0) + 1 

    maindict[m[0]]=val

Where m[0] is the 'fileID'(key for my big dictionary) and m[1]= is the file that have to be open.

When running the code, my inner dictionary is always the same but only the keys of the outer dictionary differs.like this:

{ID1:{sam:1,maj:5, tif:7, paul:1},ID2={sam:1,maj:5, tif:7, paul:1},..}

Anyone have any idea how can I fix it?

Upvotes: 0

Views: 73

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121884

You never create a new val dictionary, you just keep updating the one you created before the loop. Create a new one for each ID:

maindict = {}
for m in result:
    val = maindict.setdefault(m[0], {})
    f= open(path+m[1]+'.txt', 'r')
    for line in f:
        search_str= "my_name"
        if line.startswith(search_str):            
            linename = line.split(' ',2)[1].strip()
            key= get_name_part(linename)                       
            val[key] = val.get(key, 0) + 1 

You can simplify your code by using collections.Counter and collections.defaultdict:

from collections import Counter, defaultdict
import os

maindict = defaultdict(Counter)

for m in result:
    counts = maindict[m[0]]
    with open(os.path.join(path, m[1] + '.txt'), 'r') as f:
        search_str = "my_name"
        counts.update(get_name_part(line.split(None, 2)[1])
            for line in f if line.startswith(search_str))

Upvotes: 3

Related Questions