python: creating a list inside a dictionary

12,283

Solution 1

You're missing colons at the ends, also you could write this like:

if k not in d:
    d[k] = [v]
else:
    d[k].append(v)

Solution 2

Makes your life a little easier with defaultdict

>>> out = defaultdict(list)
>>> with open('test.txt') as f:
      for line in f.readlines():
        x = line.split()
        out[x[0]].append(int(x[2]))

It's also good practice to use the with statement to open files, when possible. Your original example had two entries as str, and one as int, I have just converted all to int here.

Solution 3

You need colons at the ends of your if statements; this version should work:

   if k in d == False:
      d[k] = []
      d[k].append(v)
   else:
      d[k].append(v)

Solution 4

Sounds like a job for defaultdict! Aside from your missing colon, as mentioned by others, you could replace the whole if with this:

from collections import defaultdict # placed with your other imports, probably
....
d = defaultdict(lambda:[])
d[k].append(v)
Share:
12,283
Keenan
Author by

Keenan

Updated on November 23, 2022

Comments

  • Keenan
    Keenan over 1 year

    I just started using python and I'm trying to create a program that will read a file that looks like this:

    AAA x 111
    AAB x 111
    AAA x 112
    AAC x 123
    ...
    

    the file is 50 lines long and I'm trying to make the letters into keys in a dictionary and the numbers lists that correspond with the keys.

    I want the output to look like this:

    {AAA: ['111', '112'], AAB: ['111'], AAC: [123], ...}
    

    This is what I've tried

    file = open("filename.txt", "r") 
    readline = file.readline().rstrip()
    while readline!= "":
        list = []
        list = readline.split(" ")
        j = list.index("x")
        k = list[0:j]
        v = list[j + 1:]
        d = {}
        if k not in d == False:
            d[k] = []
        d[k].append(v)
        readline = file.readline().rstrip()
    

    I keep getting syntax errors on my if statement and I can't figure out what I've done wrong.

    • Nathan
      Nathan over 11 years
      You could consolidate list = [] and list = readline.split(" ") into just list = readline.split(" ")- by redefining list, you're making the previous definition disappear. Also, str.split returns a list.
    • Nathan
      Nathan over 11 years
      Also, try to stay away from using list as a variable name - list is a builtin.
    • Aesthete
      Aesthete over 11 years
      @kuyan - I think your second example is supposed to be list = readline.split()?
    • Nathan
      Nathan over 11 years
      @Aesthete: You're right, I wasn't thinking.
  • Gareth Latty
    Gareth Latty over 11 years
    This is bad in a few ways. Firstly, if k not in d: would read better, you repeat d[k].append(v) instead of moving it outside the if, and you introduce a race condition into your code by not trying then catching the exception, but rather by checking beforehand. It's not likely to be a problem, but it's still a bad idea.
  • Aesthete
    Aesthete over 11 years
    The argument to the defaultdict constructor must be callable.
  • Keenan
    Keenan over 11 years
    I tried replacing the if statement with the defaultdict but I get a TypeError: first argument must be callable
  • Keenan
    Keenan over 11 years
    I followed your comments and cleaned up the code slightly. Now when the program executes I get TypeError: unhashable type: 'list'
  • acjay
    acjay over 11 years
    Sorry! My fault for not testing. Now using a lambda to make a constructor that returns the empty list. Aesthete's solution with the list constructor is probably better, but I'll leave it like this as another solution.