在Dictionary中的元组里面排序元组?

时间:2017-11-08 22:29:43

标签: python dictionary

我坚持这个Hackerrank问题,我正在为练习而做,而对于我的生活似乎无法弄清楚如何在元组中对元组进行排序?

例如,这是输入

2015-08, 2016-04

2015-08-15, clicks, 635
2016-03-24, app_installs, 683
2015-04-05, favorites, 763
2016-01-22, favorites, 788
2015-12-26, clicks, 525
2016-06-03, retweets, 101
2015-12-02, app_installs, 982
2016-09-17, app_installs, 770
2015-11-07, impressions, 245
2016-10-16, impressions, 567

我应该得到的输出是......

2016-03, app_installs, 683
2016-01, favorites, 788
2015-12, app_installs, 982, clicks, 525
2015-11, impressions, 245
2015-08, clicks, 635

但我得到的是

2016-03, app_installs, 683
2016-01, favorites, 788
2015-12, ('clicks', '525'), app_installs, 982
2015-11, impressions, 245
2015-08, clicks, 635

我的问题在于2015-12的路线。当有多个元组时,我很难按字母顺序排列。

这是我的代码

# Enter your code here. Read input from STDIN. Print output to STDOUT
from datetime import date

line = input()

startDate = line.split(',')[0]
startYear, startMonth = startDate.split('-')
startDate = date(int(startYear), int(startMonth), 1)

endDate = line.split(' ')[1]
endYear, endMonth = endDate.split('-')
endDate = date(int(endYear), int(endMonth), 1)

line = input()

d = {}
while True:
    try:
        line = input()
        currentDate = date(int(line.split('-')[0]), int(line.split('-')[1].split('-')[0]), 1)

        if startDate <= currentDate < endDate:
            engagement = line.split(',')[1].strip()
            totalEngage = line.split(',')[2].strip()
            correctDate = "{}-{}".format(currentDate.year, str(currentDate.month).zfill(2))
            if not correctDate in d:
                d[correctDate] = engagement, totalEngage
            else:
                d[correctDate] = d[correctDate], engagement, totalEngage
    except:
        break

for key in reversed(sorted(d)):
    fin = "{}, {}".format(key, ', '.join(map(str, d[key])))
    print(fin)

任何想法我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

在解决一个级别深层嵌套元组的排序问题之前,我将向您展示一种更简单的方法来解决Hackerrank问题本身。
您的解决方案的问题在于此代码段。

if not correctDate in d:
    d[correctDate] = engagement, totalEngage
else:
    d[correctDate] = d[correctDate], engagement, totalEngage

请注意,如果您在同一个月内获得 n 类型的分析,则您编写的此代码块将生成 n 级别的深层嵌套元组。这是一个演示。

>>> d = {}
>>> d["2015-12"] = "clicks", 525
>>> d["2015-12"] = d["2015-12"], "app_installs", 982
>>> d
{'2015-12': (('clicks', 525), 'app_installs', 982)}
>>> d["2015-12"] = d["2015-12"], "downloads", 100
>>> d
{'2015-12': ((('clicks', 525), 'app_installs', 982), 'downloads', 100)}

您可以使用列表存储同月的所有类型的分析。使用元组中的第一个元素作为键对该列表进行排序要简单得多。

初始化词典

d = collections.defaultdict(list)

用this-

替换有问题的代码段
d[correctDate].append( (engagement, totalEngage) )

最后,您可以显示按时间顺序按日期排序的输出,并按字母顺序在各个日期内排序。

for key in reversed(sorted(d)):

    print("{}, {}".format(key,   ', '.join( [str(elem) for elem in sorted(a, key=lambda x: x[0])])))

现在,讨论排序一个深层嵌套元组的问题。您将以某种方式展平嵌套元组以对它们进行排序。或者你可以把元组中的所有元素都带到同一级别 这样做非常笨拙的方法是 -

nested_tuple = ( ("bar", 1), "foo", 3 )
result = []
for elem, i in enumerate(nested_tuple):
    if elem is tuple:
        result.append(elem)
    else:
        result.append( (elem, nested_tuple[i+1]) )
answer = sorted(result, key=lambda x: x[0])

请再次注意,使用嵌套元组是解决此问题的一种不必要的复杂方法。但是如果你坚持使用它,你可以使用递归来排序任意级别的深层嵌套元组。