简体   繁体   中英

adding values to dictionary Python

I'm attempting to read a catalogue.txt file into dictionary. Each line contains name of the course, number of credits and a collection of 1h classes, like this: CS1P,20,Monday,14,Monday,15,Wednesday,12,Friday,12

The function I'm using:

def loadCourseCatalogue ():
    data = open ("catalogue.txt", "r+")
    print data.read ()
    all = {}
    line = data.readline ()
    while line != "":
        line = line.strip ().split (",")
        for j in line:
            all["course"] = line[0]
    return all
    print all



loadCourseCatalogue ()

The output should read like this:

all = {"course": CS1P}

after running this line:

for j in line:
        all["course"] = line[0]

and like this:

all = {"course": CS1P, "credits": 20, "timeday": [["Monday", 14], ["Monday", 15], ["Wednesday", 12], ["Friday", 12]]}

after doing it for the entire first line.

So far I've tried every possible combination for adding values found on the web and nothing works.

Your first print data.read () consumes all the data in the file and there is nothing left, try:

def loadCourseCatalogue ():
    infile = open ("catalogue.txt", "r+")
    data = infile.read ()

Then process data.

The line:

print data.read ()

consumes all input from the file and positions the file pointer at the end of the file. Subsequent reads will return an empty string, which signifies the end of the file.

I suggest that you use a for loop to iterate over the lines in your file. Also, because the lines are comma separated, you could use the csv module to assist with splitting the lines into separate fields:

import csv

def loadCourseCatalogue ():
    all = {}
    with open("catalogue.txt") as data:
        for row in csv.reader(data):
            all['course'] = row[0]
            # extract other fields into all
    return all

However, this will overwrite the values in the dictionary all as each line is processed. Instead you can use course code as a key in the dictionary, and add the rest of the data from each list to its value (also a dictionary). So aim for this data structure:

catalogue = {
    'CS1P': {'credits': 20,
             'timeday': [('Monday', 14),
                         ('Monday', 15),
                         ('Wednesday', 12),
                         ('Friday', 12)]},
    'CS2A': {'credits': 40,
             'timeday': [('Monday', 10), ('Monday', 11), ('Thursday', 12)]},
   #etc,
}

With this data structure you can easily lookup the data for a given course:

>>> catalogue['CS1P']
{'credits': 20, 'timeday': [('Monday', 14), ('Monday', 15), ('Wednesday', 12), ('Friday', 12)]}

Here's some code that will create such a dictionary:

import csv
from pprint import pprint

def loadCourseCatalogue(data):
    catalogue = {}
    for row in csv.reader(data):
        course = row[0]
        catalogue[course] = {
            'credits': int(row[1]),
            'timeday': zip(row[2::2], (int(i) for i in row[3::2]))
        }
    return catalogue

with open('catalogue.txt') as f:
    catalogue = loadCourseCatalogue(f)
    pprint(catalogue)

For input:

CS1P,20,Monday,14,Monday,15,Wednesday,12,Friday,12
CS2A,40,Monday,10,Monday,11,Thursday,12

The output is:

{'CS1P': {'credits': 20,
          'timeday': [('Monday', 14),
                      ('Monday', 15),
                      ('Wednesday', 12),
                      ('Friday', 12)]},
 'CS2A': {'credits': 40,
          'timeday': [('Monday', 10), ('Monday', 11), ('Thursday', 12)]}}

If you want to know how many credits for a course:

>>> catalogue['CS2A']['credits']
40

You are overwriting the list instead of appending the new value to it. Moreover you should also provide a default empty list for the first iteration. Replace:

all["course"] = line[0]

with:

all["course"] = all.get("course", []).append(line[0])

Also avoid the print data.read() because it will read all the file and leave nothing for the subsequent readline . If you want to let it there use data.seek(0) after printing it.

As written, this will replace the dictionary key course for each line, and you will end up with only one row in your dictionary at the end.

You can fix that by either making all a list, each value being a dict representing one row, or if your course names are all unique, you could use the course name itself as the dict key, and make its value a dict of the properties for that course.

def loadCourseCatalogue ():
    all_cources={}
    data = open("catalogue.txt","r").readlines()
    for line in data:
        _all={}
        _all['credits']=line.split(',')[1]
        _all['timeday']=line.split(',')[2:]
        all_cources[line.split(',')[0]]=_all
    return all_cources

I think you want to do something like this:

import csv
from pprint import pprint

def pairwise(iterable):
    "s -> [[s0,s1], [s2,s3], [s4, s5], ...]"
    a = iter(iterable)
    return [list(pair) for pair in zip(a, a)]

def loadCourseCatalogue():
    all = {}
    with open ("catalogue.txt", "r+") as data:
        for row in csv.reader(data):
            all[row[0]] = {'credits': row[1], 'timeday' : pairwise(row[2:])}

    pprint(all)
    return all

catalogue = loadCourseCatalogue()

For testing purposes, I extended the data file sample to:

CS1P,20,Monday,14,Monday,15,Wednesday,12,Friday,12
CS2P,19,Monday,13,Monday,14,Wednesday,11,Friday,11
CS3P,18,Monday,12,Monday,13,Wednesday,10,Friday,10

Which produced the following output:

{'CS1P': {'credits': '20',
          'timeday': [['Monday', '14'],
                      ['Monday', '15'],
                      ['Wednesday', '12'],
                      ['Friday', '12']]},
 'CS2P': {'credits': '19',
          'timeday': [['Monday', '13'],
                      ['Monday', '14'],
                      ['Wednesday', '11'],
                      ['Friday', '11']]},
 'CS3P': {'credits': '18',
          'timeday': [['Monday', '12'],
                      ['Monday', '13'],
                      ['Wednesday', '10'],
                      ['Friday', '10']]}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM