1

I have the below list of tuples:

p = [("01","Master"),("02","Node"),("03","Node"),("04","Server")]

I want my output to look like:

y = {
     "Master":{"number":["01"]},
     "Node":{"number":["02", "03"]},
     "Server":{"number":["04"]}
     }

I have tried the below code:

y = {}
for line in p:
     if line[1] in y:
          y[line[1]] = {}
          y[line[1]]["number"].append(line[0])
     else:
          y[line[1]] = {}
          y[line[1]]["number"] = [line[0]]

And I get the below error:

 Traceback (most recent call last):
         File "<stdin>", line 4, in <module>
 KeyError: 'number'

How do I solve this?

2
  • is it always in ascending order by the first ID?? Commented Dec 26, 2014 at 13:33
  • @jamylak No not necessarily Commented Dec 29, 2014 at 7:13

4 Answers 4

2
from collections import defaultdict

d = defaultdict(lambda: defaultdict(list))
for v, k in p:
    d[k]["number"].append(v)


print(d)

  defaultdict(<function <lambda> at 0x7f8005097578>, {'Node': defaultdict(<type 'list'>, {'number': ['02', '03']}), 'Master': defaultdict(<type 'list'>, {'number': ['01']}), 'Server': defaultdict(<type 'list'>, {'number': ['04']})})

without defaultdict:

d = {}
from pprint import pprint as pp
for v, k in p:
    d.setdefault(k,{"number":[]})
    d[k]["number"].append(v)


pp(d)

{'Master': {'number': ['01']},
 'Node': {'number': ['02', '03']},
 'Server': {'number': ['04']}}
Sign up to request clarification or add additional context in comments.

2 Comments

If you want to use defaultdict, then take full advantage of it: d = defaultdict(lambda: defaultdict(list)). Now all you need to do is: d[k]["number"].append(v).
@AshwiniChaudhary true, changed
1

It's because you don't initialize your dictionary when needed, and you reset it when not needed.

Try this:

p = [("01","Master"),("02","Node"),("03","Node"),("04","Server")]

y = {}
for (number, category) in p:
    if not y.get(category, False):
        # initializes your sub-dictionary
        y[category] = {"number": []}

    # adds the correct number to the sub-dictionary
    y[category]["number"].append(number)

Note that using a tuple unpacking for (number, category) in p allows your code to be more readable inside your loop.

1 Comment

This is much more sleek! Thank you!!
1

You are resetting the dictionary!

for line in p:
     if line[1] in y:
          #y[line[1]] = {}   -- RESET! ["number"] will now disappear.
                               #.. which leads to error in the next line.
          y[line[1]]["number"].append(line[0])
     else:
          y[line[1]] = {}
          y[line[1]]["number"] = [line[0]]

A more pythonic way of achieving the same thing would be by using a defaultdict as demonstrated in other answers.

1 Comment

Thank you! This works!! I knew I was making a stupid mistake somewhere! Thanks a lot!
1

Do not assign {} to key when key is already present in y.

y = {}
for line in p:
     try:
          y[line[1]]["number"].append(line[0])
     except:
          y[line[1]] = {}
          y[line[1]]["number"] = [line[0]]

OR Use defaultdict use:-

>>> from collections import defaultdict
>>> p = [("01","Master"),("02","Node"),("03","Node"),("04","Server")]
>>> d = defaultdict(list)
>>> for k, v in p:
...    d[v].append(k)
... 
>>> d
defaultdict(<type 'list'>, {'Node': ['02', '03'], 'Master': ['01'], 'Server': ['04']})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.