Python 从文本文件中提取信息并将其转换为字典

Python 从文本文件中提取信息并将其转换为字典,python,Python,Python新手,如果这太容易的话,很抱歉,我通常使用R,但我想尝试一下。我正在尝试将一个包含学生编号、课程ID(共7门课程)和评分的csv文件转换为字典。它与其他问题不同,因为csv文件中的密钥不是唯一的值,它是根据该学生评估的课程数量随机复制的。示例数据如下所示: participant_id;course_id;rating 103;4;2 104;5;3.5 104;7;2.5 108;3;3.5 108;5;2 114;2;4.5 114;5;3.5 114;7;4.5 116;1;2

Python新手,如果这太容易的话,很抱歉,我通常使用R,但我想尝试一下。我正在尝试将一个包含学生编号、课程ID(共7门课程)和评分的csv文件转换为字典。它与其他问题不同,因为csv文件中的密钥不是唯一的值,它是根据该学生评估的课程数量随机复制的。示例数据如下所示:

participant_id;course_id;rating
103;4;2
104;5;3.5
104;7;2.5
108;3;3.5
108;5;2
114;2;4.5
114;5;3.5
114;7;4.5
116;1;2
116;2;3
116;3;3
116;4;4
126;5;3
129;1;4
129;5;3.5
135;1;4.5
def ratings(filename):
    d = {}
    max_col = 0                                     # Number of columns needed. Maximum course_id.
    idx_col_val_list = []

    with open(filename) as fp:
        fp.readline()                               # Ignore "participant_id;course_id;rating"

        for line in fp.readlines():
            line = line.strip()
            idx, col, val = line.split(';')
            col = int(col)
            val = float(val)

            max_col = max(max_col, col)
            idx_col_val_list.append((idx, col, val))

    for idx, col, val in idx_col_val_list:
        if idx not in d:
            d[idx] = ['NA'] * max_col
        d[idx][col - 1] = val

    return d


ans = ratings('input.txt')

assert ans == {
    '103': ['NA', 'NA', 'NA', 2.0, 'NA', 'NA', 'NA'],
    '104': ['NA', 'NA', 'NA', 'NA', 3.5, 'NA', 2.5],
    '108': ['NA', 'NA', 3.5, 'NA',2.0, 'NA', 'NA'],
    '114': ['NA', 4.5, 'NA', 'NA', 3.5, 'NA', 4.5],
    '116': [2.0, 3.0, 3.0, 4.0, 'NA', 'NA', 'NA'],
    '126': ['NA', 'NA', 'NA', 'NA', 3.0, 'NA', 'NA'],
    '129': [4.0, 'NA', 'NA', 'NA', 3.5, 'NA', 'NA'],
    '135': [4.5, 'NA', 'NA', 'NA', 'NA', 'NA', 'NA'],
}
所以最佳结果是这样的,学生人数是关键,值是一个列表,课程id是列表的索引,评分是值。剩下的就不一样了

{'103': ['NA', 'NA', 'NA', 2.0, 'NA', 'NA', 'NA'],
 '104': ['NA', 'NA', 'NA', 'NA', 3.5, 'NA', 2.5],
 '108': ['NA', 'NA', '3.5, 'NA',2.0', 'NA', 'NA'],
 '114': ['NA', 4.5, 'NA', 'NA', 3.5, 'NA', '4.5],
 '116': [2.0, 3.0, 3.0, 4.0, 'NA', 'NA', 'NA'],
 '126': ['NA', 'NA', 'NA', 'NA', 3.0, 'NA', 'NA'],
 '129': [4.0, 'NA', 'NA', 'NA', '3.5, 'NA', 'NA'],
 '135': [4.5, 'NA', 'NA', 'NA', 'NA', 'NA', 'NA']}
我尝试使用set()提取学生编号,现在每个学生编号都有唯一的值,我所能做的就是用正确的键列出一个列表,但所有课程评分都是NA,因为我不知道如何提取课程id和分组评分,并将其放入列表中。以下是我目前的代码:

def ratings(filename):
    with open(filename) as fp: 
        buffer = fp.readlines()
        stu_id = []
        dic = {}

        for i in (buffer):
            stu_id.append(i.split(';')[0])
            stu_id_set = list(set(stu_id))
            for j in stu_id_set:
                dic[j] = ['NA','NA','NA','NA','NA','NA','NA']
    return dic



我们可以这样做:

participant_id;course_id;rating
103;4;2
104;5;3.5
104;7;2.5
108;3;3.5
108;5;2
114;2;4.5
114;5;3.5
114;7;4.5
116;1;2
116;2;3
116;3;3
116;4;4
126;5;3
129;1;4
129;5;3.5
135;1;4.5
def ratings(filename):
    d = {}
    max_col = 0                                     # Number of columns needed. Maximum course_id.
    idx_col_val_list = []

    with open(filename) as fp:
        fp.readline()                               # Ignore "participant_id;course_id;rating"

        for line in fp.readlines():
            line = line.strip()
            idx, col, val = line.split(';')
            col = int(col)
            val = float(val)

            max_col = max(max_col, col)
            idx_col_val_list.append((idx, col, val))

    for idx, col, val in idx_col_val_list:
        if idx not in d:
            d[idx] = ['NA'] * max_col
        d[idx][col - 1] = val

    return d


ans = ratings('input.txt')

assert ans == {
    '103': ['NA', 'NA', 'NA', 2.0, 'NA', 'NA', 'NA'],
    '104': ['NA', 'NA', 'NA', 'NA', 3.5, 'NA', 2.5],
    '108': ['NA', 'NA', 3.5, 'NA',2.0, 'NA', 'NA'],
    '114': ['NA', 4.5, 'NA', 'NA', 3.5, 'NA', 4.5],
    '116': [2.0, 3.0, 3.0, 4.0, 'NA', 'NA', 'NA'],
    '126': ['NA', 'NA', 'NA', 'NA', 3.0, 'NA', 'NA'],
    '129': [4.0, 'NA', 'NA', 'NA', 3.5, 'NA', 'NA'],
    '135': [4.5, 'NA', 'NA', 'NA', 'NA', 'NA', 'NA'],
}

我们可以这样做:

participant_id;course_id;rating
103;4;2
104;5;3.5
104;7;2.5
108;3;3.5
108;5;2
114;2;4.5
114;5;3.5
114;7;4.5
116;1;2
116;2;3
116;3;3
116;4;4
126;5;3
129;1;4
129;5;3.5
135;1;4.5
def ratings(filename):
    d = {}
    max_col = 0                                     # Number of columns needed. Maximum course_id.
    idx_col_val_list = []

    with open(filename) as fp:
        fp.readline()                               # Ignore "participant_id;course_id;rating"

        for line in fp.readlines():
            line = line.strip()
            idx, col, val = line.split(';')
            col = int(col)
            val = float(val)

            max_col = max(max_col, col)
            idx_col_val_list.append((idx, col, val))

    for idx, col, val in idx_col_val_list:
        if idx not in d:
            d[idx] = ['NA'] * max_col
        d[idx][col - 1] = val

    return d


ans = ratings('input.txt')

assert ans == {
    '103': ['NA', 'NA', 'NA', 2.0, 'NA', 'NA', 'NA'],
    '104': ['NA', 'NA', 'NA', 'NA', 3.5, 'NA', 2.5],
    '108': ['NA', 'NA', 3.5, 'NA',2.0, 'NA', 'NA'],
    '114': ['NA', 4.5, 'NA', 'NA', 3.5, 'NA', 4.5],
    '116': [2.0, 3.0, 3.0, 4.0, 'NA', 'NA', 'NA'],
    '126': ['NA', 'NA', 'NA', 'NA', 3.0, 'NA', 'NA'],
    '129': [4.0, 'NA', 'NA', 'NA', 3.5, 'NA', 'NA'],
    '135': [4.5, 'NA', 'NA', 'NA', 'NA', 'NA', 'NA'],
}

这里有一个使用
pandas
和字典的简洁方法:

import pandas as pd

df = pd.read_csv('your_csv_file.csv')

# build a list of dictionaries
# each element will lool like {'participant_id':104, 'course_id':4, 'rating':2}
records = df.to_dict(orient='records')

# initialize the final dictionary
# assign a 7-element list to each participant, filled with zeros
performance = {i['participant_id']:7*[0] for i in records}

# populate the final dictionary
for r in records:
    performance[r['participant_id']][r['course_id']] = r['rating']

这里有一个使用
pandas
和字典的简洁方法:

import pandas as pd

df = pd.read_csv('your_csv_file.csv')

# build a list of dictionaries
# each element will lool like {'participant_id':104, 'course_id':4, 'rating':2}
records = df.to_dict(orient='records')

# initialize the final dictionary
# assign a 7-element list to each participant, filled with zeros
performance = {i['participant_id']:7*[0] for i in records}

# populate the final dictionary
for r in records:
    performance[r['participant_id']][r['course_id']] = r['rating']

可能重复的可能重复的可能重复的hello Dipen,谢谢你回答这个问题。我还有一个问题:如何使用fp.readline()删除参与者id;课程编号;评级部分?我一直认为readline()和readlines()之间的唯一区别在于readlines()同时读取更多的行。因此,在调用readline()之后,该文件会弹出文件的第一行?您可能想看看Python官方文档中的示例<代码>读取行()一次读取一行。所以,我们用它删除了第一行,然后使用了后面的几行。你好,迪本,谢谢你回答这个问题。我还有一个问题:如何使用fp.readline()删除参与者id;课程编号;评级部分?我一直认为readline()和readlines()之间的唯一区别在于readlines()同时读取更多的行。因此,在调用readline()之后,该文件会弹出文件的第一行?您可能想看看Python官方文档中的示例<代码>读取行()一次读取一行。因此,我们使用它删除第一行,然后使用后续行。