0

Edit: TL;DR

What I have:

dict_1 = {'file1': {'word1': 5, 'word2: 3'}, 'file2': {'word1': 12, 'word2: 0'}}


dict_2 = {'file1': {'total_words': 11}, 'file2': {'total_words': 18}}

What I want

concat_dict = {'file1': {'word1': 5, 'word2: 3', 'total_words' : 11}, 'file2': {'word1': 12, 'word2: 0', 'total_words' : 18}} 

Which has added a associated value from dict_2 to the common key in dict_1. I have a dictionary that is composed of text file names and the word-count of specific words in those files.

Original post

I want to add also a count for the total words in each file (value for each key), in addition to the specific words in each file, how would I do that?

My code:

# dict_one = previously defined
# filter_words = previously defined
out={}
for k, v in dict_one.items():
    #create empty list
    new = []
    #for each filter word
    for i in filter_words:
        new.extend(re.findall(r"{}".format(i),v) )

    out[k] = dict(Counter(new))

# count total number of words
total_dict = {k: len(v) for k,v in dict_one.items()}

Basically, I want to concatenate total_dict{} and out{} dictionaries, as they have the same keys but I'm unsure how.

Also: I haven't gone through this code in a while, but I forgot what this expression does:

new.extend(re.findall(r"{}".format(i),v) )

I know it's extending the list, but im confused by the arguments of re.findall:

r"{}".format(i),v)

what does this mean/do?

HonsTh
  • 65
  • 7
  • 1
    In this particular example, `"{}".format(i)` is similar to `str(i)`; The `r` is unnecessary. See [Format String Syntax](https://docs.python.org/3.4/library/string.html#format-string-syntax) –  Sep 05 '19 at 01:13

1 Answers1

1

You can use a dictionary comprehension and the approach described in this answer to merge the internal dicts:

dict_1 = {'file1': {'word1': 5, 'word2': '3'}, 'file2': {'word1': 12, 'word2': '0'}}
dict_2 = {'file1': {'total_words': 11}, 'file2': {'total_words': 18}}

concat_dict = {k:{**dict_1[k], **dict_2[k]} for k in dict_1}
concat_dict

Output:

{'file1': {'word1': 5, 'word2': '3', 'total_words': 11},
 'file2': {'word1': 12, 'word2': '0', 'total_words': 18}}
foglerit
  • 7,792
  • 8
  • 44
  • 64
  • I'm getting a strange error I can't seem to find online: **TypeError: 'int' object is not a mapping** – HonsTh Sep 05 '19 at 01:29
  • 1
    Your example had a couple of typos that I had to fix. For example, this string `'word2: 3'` should be `'word2': '3'`. Try to fix those or copy-paste my code to check that it runs. – foglerit Sep 05 '19 at 02:06
  • Copying and pasting your code actually works. But it doesn't seem to be working when I use my actual dictionaries. For example, I have: `dict_1 = {'file1': {'word1': 2}} dict_2 = {'file1': 190952} concat = {} concat = {k:{**dict_1[k], **dict_2[k]} for k in dict_1}` Which returns the error 'int' object is not a mapping. I copied and pasted those key/value pairs into my dict_1 and dict_2 creations from the console. – HonsTh Sep 05 '19 at 02:10
  • Sorry! I just figured it out. My second dictionary doesn't have a proper key-value pair in the same format as the original dictionary. – HonsTh Sep 05 '19 at 02:12
  • Exactly. If your `dict_2` is instead like the one in your example, you can use `concat = {k:{**dict_1[k], **{'total_words': dict_2[k]}} for k in dict_1}` – foglerit Sep 05 '19 at 02:15
  • I know this is a separate question altogether, but would you know how to get my `dict_2 = {'file1': 190952}` so that it's `dict_2 = {'file1': {'total_words': 190952}}` ? to create `dict_2` I used `dict_2 = {k: len(v) for k,v in dict_one.items()}` – HonsTh Sep 05 '19 at 02:19
  • 1
    You can create `dict_2` as `dict_2 = {k: {'total_words':len(v)} for k,v in dict_one.items()}` – foglerit Sep 05 '19 at 02:23