Python Dictionary Throwing KeyError for adding list of tuples

Question:

Here is original text file:

s1 10 s2
s2 12 s3
s3 25 s1
s1 14 s3

I am making a dictionary of first value in each line as a key, the output should be:
{‘s1’: [(‘s2’, ‘s10’), (‘s3′, ’14’)], ‘s2’: [(‘s3′, ’12’)], ‘s3’: [(‘s1′, ’25’)]}

When i run my code I get a key error:

def graph_dict(filename):
    dictx = {}
    with open(filename) as x:
        for i in x:
            c, c1, c2 = i.split()
            dictx[c] += [(c2,c1)]
        return dictx

Traceback (most recent call last):
  File "<pyshell#361>", line 1, in <module>
    graph_dict("filename.txt")
  File "*********************************************", line 7, in graph_dict
    dictx[c] += [(c2,c1)]
KeyError: 's1'

in the above line when I make it into dictx[c] = [(c2,c1)] I get output;

{'s1': [('s3', '14')], 's2': [('s3', '12')], 's3': [('s1', '25')]}

And so it is throwing a key error as attempting to add a list of 2 tuples to "s1", which I thought should be okay. Does anyone have advice to get output:

{'s1': [('s2', 's10'), ('s3', '14')], 's2': [('s3', '12')], 's3': [('s1', '25')]}

Thanks

Asked By: hfak

||

Answers:

Use .setdefault()

def graph_dict(filename):
    dictx = {}
    with open(filename) as x:
        for i in x:
            c, c1, c2 = i.split()
            dictx.setdefault(c,[]).append((c2,c1))
        return dictx
print(graph_dict(r'c:testdat.txt'))
{'s1': [('s2', '10'), ('s3', '14')], 's2': [('s3', '12')], 's3': [('s1', '25')]}
Answered By: Алексей Р

dictx[c] += [(c2,c1)] assumes that c already exists in the dictionary. You could test instead. And use .append to be a little faster.

def graph_dict(filename):
    dictx = {}
    with open(filename) as x:
        for i in x:
            c, c1, c2 = i.split()
            if c in dictx:
                dictx[c].append((c2,c1))
            else:
                dictx[c] = [(c2, c1)]
        return dictx
Answered By: tdelaney
from collections import defaultdict 

def graph_dict(filename):
    dictx = defaultdict(list)
    with open(filename) as x:
        for i in x:
            c, c1, c2 = i.split()
            dictx[c] += [(c2,c1)]
        return dictx

print(graph_dict('data'))
Answered By: Mark

Aside of using defaultdict, you can try to catch that exception (known as It’s Easier To Ask Forgiveness Than To Get Permission):

def graph_dict(filename):
    dictx = {}
    with open(filename) as x:
            for i in x:
                c, c1, c2 = i.split()
                try:
                    dictx[c] += [(c2,c1)]
                except KeyError:
                    dictx[c] = [(c2, c1)]
    return dictx
Answered By: Steven
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.