使用for循环创建词典列表

时间:2019-12-15 21:14:08

标签: python python-3.x

我正在尝试获取以下代码:

dirpath = os.getcwd()
path = f"{dirpath}/static/user_images/user_{user_id}"
l = []
ratings_list = []
for filename in Path(path).glob('**/*.*'):
    file = os.path.basename(filename)
    query = text('SELECT * FROM ratings WHERE photo_name = "{}" AND photo_user_id = {}'.format(file, user_id))
    resultproxy = db.session.execute(query)

    for row in resultproxy:
        l.append(row.rating)
        total_ratings_count = len(l)
        average = statistics.mean(l)
        lowest = min(l)
        highest = max(l)

        data = {
        file: average, 
        "min": lowest,
        "max": highest,
        "number_of_ratings": total_ratings_count
        }
        ratings_list.append(data)

输出一个字典列表,每个字典都有图像名称,以及最大,最小,平均评级; 像这样:

[
{"image_name": avg_rating, "max": max_rating, "min": min_rating, "number_of_ratings": ratings_count},
{"image_name_2": avg_rating, "max": max_rating, "min": min_rating, "number_of_ratings": ratings_count},
{"image_name_3": avg_rating, "max": max_rating, "min": min_rating, "number_of_ratings": ratings_count},
]

相反,我得到的是每张图像重复的单个值(即,如果记录了4个评分,则将返回4个条目,并带有其单独评分而不是平均值)

当我将数据项移出第二个for循环时,如下所示:

for filename in Path(path).glob('**/*.*'):
    file = os.path.basename(filename)
    query = text('SELECT * FROM ratings WHERE photo_name = "{}" AND photo_user_id = {}'.format(file, user_id))
    resultproxy = db.session.execute(query)

    for row in resultproxy:
        l.append(row.rating)
    total_ratings_count = len(l)
    average = statistics.mean(l)
    lowest = min(l)
    highest = max(l)

    data = {
    file: average,
    "min": lowest,
    "max": highest,
    "number_of_ratings": total_ratings_count
    }
    ratings_list.append(data)

我收到错误statistics.StatisticsError: mean requires at least one data point。当我print(l)时,它返回一个空列表。

1 个答案:

答案 0 :(得分:0)

好吧,所以我发现最简单的方法是让sql进行数学运算,这似乎消除了复杂性。工作代码为:

    @classmethod
    def load_user_ratings(cls, user_id) -> dict:
        dirpath = os.getcwd()
        path = f"{dirpath}/static/user_images/user_{user_id}"
        d = {}
        ratings_list = []
        for filename in Path(path).glob('**/*.*'):
            file = os.path.basename(filename)
            sql = text('SELECT AVG(rating) as average, MAX(rating) as maximum, MIN(rating) as minimum FROM ratings '
                       'WHERE photo_name = "{}" AND photo_user_id = {}'.format(file, user_id))
            resultproxy = db.session.execute(sql)

            for row in resultproxy:
                for column, value in row.items():
                    # build up the dictionary
                    d = {**d, **{column: value}}
                    d.update({"image": file})
            ratings_list.append(d)
    return ratings_list

为清楚起见,resultproxy是一个sqlalchemy对象,其输出类似于<sqlalchemy.engine.result.ResultProxy object at 0x10fdbfad0>

此问题的真正问题是在完成数学工作后,将结果正确放入字典中。只要将ratings_list.append(d)移到第二个for循环之外,就可以完成该操作,只要该SQL查询正在处理AVG / MIN / MAX。否则,您将得到一个statistics.StatisticsError: mean requires at least one data point错误,该错误在终端上打印时显示初始列表为空,然后迭代填充。

我认为这是有道理的,但是我无法弄清楚如何让python正确处理数字。这是一个临时性的IMO,因为我怀疑在某些时候我需要做一些SQL不能提供的更复杂的数学。