Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, what is the easiest way to add a list consisting of keyword pairs to a dictionary?

I have a homework problem in Python.
I am using Python version 3.4.0 on Linux.
The design document states that I am to read a CSV file using built in functions, specified as names.dat, that is in the format:

name:name2, name:name3, name2:name4, name3:name5\n (etc)

I am then to add these keyword pairs to a dictionary, which is the part I'm stuck on.
The code I have thus far is this:

dictionary = dict()
database = open('names.dat', 'r')
data = database.read()
data = data.rstrip('\n')
data = data.split(',')
for item in range(len(data)):
    dictionary.update(data[item-1])

My thinking being that if I have a list element in the format "name:name2", and I call the dictionary update function with that element as an argument, it will properly map to a keyword pair in the dictionary.
However, this is not the case, as I get this error when I run this script:

File "MyName.py", line 7, in <module>
    dictionary.update(data[item-1])
ValueError: dictionary update sequence element #0 has length 1; 2 is required

This and This seem similar, but I feel that this is enough of a different question to warrant a separate response.
What am I doing wrong here, and how can I fix it?
Is there a simpler way to do this?

like image 233
Torger597 Avatar asked Mar 19 '15 03:03

Torger597


People also ask

How do you add a key-value pair to a list in Python?

There is no "key-value pair" as a general thing in Python. Why are you using a list instead of a dictionary? A dictionary contains key-value pairs, but there's no builtin notion of a key-value pair that's not in a dictionary.

How do I add a list to a Python dictionary?

Method 1: Using += sign on a key with an empty value In this method, we will use the += operator to append a list into the dictionary, for this we will take a dictionary and then add elements as a list into the dictionary.


2 Answers

@Paulo Scardine has a great answer if you want to create an exact dataset from the given csv. If you want to combine the values based on the key one could use this:

changes = {}
with open('test.csv', 'r') as f:
    for row in f:
        for e in row.rstrip('\n').split(", ") : #split lines by column
            print (e) #just to show what is being generated here
            (k,v) = e.split(":") #split further into key, value pairs
            changes.setdefault(k, []).append(v)
            #creates empty list if new key, adds value to list

print (changes)

Data will look like:

{'name3': ['name5'], 'name2': ['name4', 'name6', 'name5'], 'name1': ['name', 'name4'], 'name': ['name2', 'name3']}

This could be further simplified but I think this gives the good example that someone learning can follow.

Edit: added setdefault method following @Paulo Scardine comment

like image 173
LinkBerest Avatar answered Oct 16 '22 10:10

LinkBerest


Try this:

data = []
with open('names.dat') as database:
    for line in database:
        if line.strip():  # skip blank lines
            data.append(
                dict(i.split(":") for i in line.rstrip('\n').split(","))
            )

If your file is:

name:name2,name:name3,name2:name4,name3:name5
name:name2,name:name3,name2:name4,name3:name5
name:name2,name:name3,name2:name4,name3:name5
name:name2,name:name3,name2:name4,name3:name5

data will be:

[{'name': 'name3', 'name2': 'name4', 'name3': 'name5'},
 {'name': 'name3', 'name2': 'name4', 'name3': 'name5'},
 {'name': 'name3', 'name2': 'name4', 'name3': 'name5'},
 {'name': 'name3', 'name2': 'name4', 'name3': 'name5'}]

Perhaps you want a dict of list instead of a list of dict:

data = {}
with open('names.dat') as database:
    for line in database:
        if line.strip():  # skip blank lines
            for k, v in (i.split(":") for i in line.rstrip('\n').split(",")):
                data.setdefault(k, []).append(v)

Resulting:

{'name': [ 'name2', 'name3', 'name2', 'name3', 'name2', 'name3', 'name2', 'name3'],
 'name2': ['name4', 'name4', 'name4', 'name4'],
 'name3': ['name5', 'name5', 'name5', 'name5']}
like image 41
Paulo Scardine Avatar answered Oct 16 '22 10:10

Paulo Scardine