PopeJohnPaulII
PopeJohnPaulII

Reputation: 775

Create a dict of lists

Hopefully I've explained it well enough in the title but here is what I have:

Input data:

Mushroom Kingdom, Mario

Hyrule, Link

Mushroom Kingdom, Bowser

Zebes, Samus

Zebes, Metroid

And I want to run something like this,

# The next three lines establish that I'll be reading proc as a file
import subprocess
cmd = 'external command that returns the above data'
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)

homeworlds = {}

while True:
  line = proc.stdout.readline().split(',')
  if line:
    # If line isn't empty
    homeword = line[0]
    person = line[1]

    homeworlds[homeword] = list.append[person] # Good logic? Bad syntax?

  else:
   break

The goal is that I'll be able to call:

print homeworlds['Mushroom Kingdom']

and return the list

Mario, Bowser

Upvotes: 2

Views: 166

Answers (6)

Alexis Huet
Alexis Huet

Reputation: 765

Here is a consistant and elegant solutions (partially inspired from other answers) :

#!/bin/env python
from collections import defaultdict

lines = """Mushroom Kingdom, Mario

Hyrule, Link

Mushroom Kingdom, Bowser

Zebes, Samus

Zebes, Metroid
"""

homeworlds = defaultdict(list)

for line in lines.splitlines():
    if line and ',' in line:
        key, value = line.split(',')
        homeworlds[key].append(value.trim())

print(homeworlds)

Upvotes: 0

inspectorG4dget
inspectorG4dget

Reputation: 114025

It's easier to use a defaultdict here. Also, you're curretnly calling split() without any parameters. What you really want to do is split on the ,. So you should call split(',').

So your code should look somewhat like this:

homeworlds = collections.defaultdict(list)
while True:
  line = proc.stdout.readline().split(',')
  if line:
    # If line isn't empty
    homeworld = line[0].strip()
    person = line[1].strip()

    homeworlds[homeworld].append(person)

  else:
    break

Upvotes: 2

user6498743
user6498743

Reputation: 1

Python 2.7.3rc2 (default, Apr 22 2012, 22:30:17) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> input_data = [('Mushroom Kingdom', 'Mario'),
...  ('Hyrule', 'Link'),
...  ('Mushroom Kingdom', 'Bowser'),
...  ('Zebes', 'Samus'),
...  ('Zebes', 'Metroid')]
>>> homeworlds = {}
>>> for homeword,person in input_data:
...   homeworlds.setdefault(homeword, []).append(person)
... 
>>> homeworlds
{'Hyrule': ['Link'], 'Zebes': ['Samus', 'Metroid'], 'Mushroom Kingdom': ['Mario', 'Bowser']}
>>> print(homeworlds['Mushroom Kingdom'])
['Mario', 'Bowser']
>>> print("{0}".format(', '.join(homeworlds['Mushroom Kingdom'])))
Mario, Bowser

in your case swap in for loop: 'input_data' for 'line'

Upvotes: 0

applicative_functor
applicative_functor

Reputation: 4976

Use defaultdict

from collections import defaultdict
homeworlds = defaultdict(list)

homeworlds[homeword].append(person)

Upvotes: 0

Sam Mussmann
Sam Mussmann

Reputation: 5993

Try this:

if homeword not in homeworlds:
    homeworlds[homeword] = []
homeworlds[homeword].append(person)

This checks to see if there's an entry for homeword in homeworld. If there's not, it adds a list there. Then we know for sure that we have a list at homeworld[homeword] so we can just call .append(person) on it.

Upvotes: 0

user2665694
user2665694

Reputation:

 if not homeword in homeworlds:
    homeworlds[homeword] = list()
 homeworlds[homeword].append(person)

Upvotes: 2

Related Questions