简体   繁体   English

排序嵌套字典

[英]Sorting nested dictionary

I have some data, which look like this:我有一些数据,如下所示:

tuplelist = [
    (datetime.date(2020, 4, 20), 4.23, 'EUR'),
    (datetime.date(2020, 4, 20), 3.76, 'USD'),
    (datetime.date(2020, 4, 20), 4.21, 'EUR'),
    (datetime.date(2020, 4, 20), 5.20, 'GPB'),
    (datetime.date(2020, 4, 20), 3.77, 'USD'),
    (datetime.date(2020, 4, 20), 4.27, 'EUR'),
    (datetime.date(2020, 4, 20), 3.79, 'USD'),
    (datetime.date(2020, 4, 20), 4.30, 'EUR'),
    (datetime.date(2020, 4, 20), 5.14, 'GPB'),
    (datetime.date(2020, 4, 20), 3.77, 'USD'),
    (datetime.date(2020, 4, 25), 4.23, 'EUR'),
    (datetime.date(2020, 4, 25), 3.76, 'USD'),
    (datetime.date(2020, 4, 25), 4.21, 'EUR'),
    (datetime.date(2020, 4, 25), 5.20, 'GPB'),
    (datetime.date(2020, 4, 25), 3.77, 'USD'),
    (datetime.date(2020, 4, 27), 4.27, 'EUR'),
    (datetime.date(2020, 4, 27), 3.79, 'USD'),
    (datetime.date(2020, 4, 27), 4.30, 'EUR'),
    (datetime.date(2020, 4, 27), 5.14, 'GPB'),
    (datetime.date(2020, 4, 28), 3.77, 'USD'),
    (datetime.date(2020, 4, 28), 4.23, 'EUR'),
    (datetime.date(2020, 5, 2), 3.76, 'USD'),
    (datetime.date(2020, 5, 2), 4.21, 'EUR'),
    (datetime.date(2020, 5, 2), 5.20, 'GPB'),
    (datetime.date(2020, 5, 2), 3.77, 'USD'),
    (datetime.date(2020, 5, 2), 4.27, 'EUR'),
    (datetime.date(2020, 5, 5), 3.79, 'USD'),
    (datetime.date(2020, 5, 5), 4.30, 'EUR'),
    (datetime.date(2020, 5, 5), 5.14, 'GPB'),
    (datetime.date(2020, 5, 5), 3.77, 'USD'),
    (datetime.date(2020, 4, 20), 4.23, 'EUR'),
    (datetime.date(2020, 4, 20), 3.76, 'USD'),
    (datetime.date(2020, 4, 20), 4.21, 'EUR'),
    (datetime.date(2020, 4, 20), 5.20, 'GPB'),
    (datetime.date(2020, 4, 20), 3.77, 'USD'),
    (datetime.date(2020, 4, 20), 4.27, 'EUR'),
    (datetime.date(2020, 4, 20), 3.79, 'USD'),
    (datetime.date(2020, 4, 20), 4.30, 'EUR'),
    (datetime.date(2020, 4, 20), 5.14, 'GPB'),
    (datetime.date(2020, 4, 20), 3.77, 'USD'),
    (datetime.date(2020, 4, 25), 4.23, 'EUR'),
    (datetime.date(2020, 4, 25), 3.76, 'USD'),
    (datetime.date(2020, 4, 25), 4.21, 'EUR'),
    (datetime.date(2020, 4, 25), 5.20, 'GPB'),
    (datetime.date(2020, 4, 25), 3.77, 'USD'),
    (datetime.date(2020, 4, 27), 4.27, 'EUR'),
    (datetime.date(2020, 4, 27), 3.79, 'USD'),
    (datetime.date(2020, 4, 27), 4.30, 'EUR'),
    (datetime.date(2020, 4, 27), 5.14, 'GPB'),
    (datetime.date(2020, 4, 28), 3.77, 'USD'),
    (datetime.date(2020, 4, 28), 4.23, 'EUR'),
    (datetime.date(2020, 5, 2), 3.76, 'USD'),
    (datetime.date(2020, 5, 2), 4.21, 'EUR'),
    (datetime.date(2020, 5, 2), 5.20, 'GPB'),
    (datetime.date(2020, 5, 2), 3.77, 'USD'),
    (datetime.date(2020, 5, 2), 4.27, 'EUR'),
    (datetime.date(2020, 5, 5), 3.79, 'USD'),
    (datetime.date(2020, 5, 5), 4.30, 'EUR'),
    (datetime.date(2020, 5, 5), 5.14, 'GPB'),
    (datetime.date(2020, 5, 5), 3.77, 'USD')
]

I managed to group it by date an currency and sum the values of each curriency.我设法按日期对货币进行分组,并对每种货币的价值求和。 Now, I'd like to sort the currency values in descending manner.现在,我想按降序对货币值进行排序。 However I got some problems with two values (the same problem is during sorting in ascending way, but then this values are at the end):但是我遇到了两个值的一些问题(同样的问题是在升序排序期间,但是这个值在最后): 输出

Do you have any clue if my sorting loop is correct?如果我的排序循环正确,您有任何线索吗? Moreover, it is possible not to change the dictionary to list, while sorting?此外,排序时可以不将字典更改为列表吗?

Here is my code:这是我的代码:

# grouping elements by date and currency
result = {}
for key, values in groupby(tuplelist, lambda x: x[0]):
    for _, v1, v2 in values:
        result.setdefault(key, {}).setdefault(v2, []).append(v1)

# summing value of each currency of each day
result2 = {}
for key, values in result.items():
    for k, val in values.items():
        total = sum(val)
        result2.setdefault(key, {}).setdefault(k, "%.2f" % total)

print("-----------------------BEFORE SORTING------------------------------------")
for items in result2.items():
    print(items)

# sorting the values of currencies in descending order
sorted_dict = {}
for key, values in result2.items():
    sorted_values = sorted(values.items(), key=lambda item: item[1], reverse=True)
    sorted_dict[key] = sorted_values

print("-----------------------SORTED VALUES------------------------------------")
for items in sorted_dict.items():
    print(items)
# grouping elements by date and currency
result = {}
for key, values in groupby(tuplelist, lambda x: x[0]):
    for _, v1, v2 in values:
        result.setdefault(key, {}).setdefault(v2, []).append(v1)

# summing value of each currency of each day
result2 = {}
for key, values in result.items():
    for k, val in values.items():
        total = sum(val)
        result2.setdefault(key, {}).setdefault(k, round(total,2))

print("-----------------------BEFORE SORTING------------------------------------")
for items in result2.items():
    print(items)

# sorting the values of currencies in descending order
sorted_dict = {}
for key, values in result2.items():
    sorted_values = sorted(values.items(), key=lambda item: item[1], reverse=True)
    sorted_dict[key] = sorted_values

print("-----------------------SORTED VALUES------------------------------------")
for items in sorted_dict.items():
    print(items)

I make a change at result2 where i change <"%.2f" % total> to <round(total,2)> as by using <"%.2f" % total> will turn your value to string, therefore unable to sort as per your requirement.我在 result2 进行了更改,我将 <"%.2f" % total> 更改为 <round(total,2)> 因为使用 <"%.2f" % total> 会将您的值转换为字符串,因此无法排序根据您的要求。

As Shlim mentioned in his answer, the sorting in your current output is correct if you were sorting by string values.正如 Shlim 在他的回答中提到的,如果您按字符串值排序,则当前输出中的排序是正确的。 In order to sort them by their numeric values you can make the adjustments Shlim suggests.为了按数值对它们进行排序,您可以进行 Shlim 建议的调整。

My suggestion is instead of having so many loops and creating so many external data structures, why not just make it one loop and one external dictionary?我的建议是不要有这么多循环和创建这么多外部数据结构,为什么不让它成为一个循环和一个外部字典呢? For example:例如:

result = {}
for key, values in groupby(tuplelist, lambda x: x[0]):
    for _, v1, v2 in values:
        if key in result and v2 in result[key]:
            result[key][v2] += v1
        elif key not in result:
            result[key] = {v2: v1}
        else:
            result[key][v2] = v1
    sorted_values = sorted(
        result[key].items(), key=lambda item: item[1], reverse=True
    )
    rounded = map(lambda x: (x[0], round(x[1],2)), sorted_values)
    result[key].update(list(rounded))

To answer your other question, you cannot sort a dictionary directly with any of the builtin sorting functions.要回答您的其他问题,您不能直接使用任何内置排序功能对字典进行排序。 This is because they all rely on integer indexes which dictionaries do not have.这是因为它们都依赖于字典没有的整数索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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