Вопрос:

Сортировать кортеж внутри кортежа внутри словаря?

python dictionary

89 просмотра

1 ответ

3 Репутация автора

Я застрял в этом хакерранковском вопросе, который я задаю для практики, и, судя по всему, не могу понять, как отсортировать кортеж внутри кортежа?

Например, это вход

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)

Есть идеи, что я делаю не так?

Спасибо!

Автор: SortStuff Источник Размещён: 08.11.2017 10:29

Ответы (1)


2 плюса

128 Репутация автора

Решение

Прежде чем заняться проблемой сортировки одноуровневых вложенных кортежей, я покажу вам более простой способ решения самой проблемы 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)

Замените проблемный сегмент кода этим-

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])

Опять же, обратите внимание, что использование вложенных кортежей является излишне сложным подходом для решения этой проблемы. Но если вы настаиваете на его использовании, вы можете использовать рекурсию для сортировки вложенных кортежей произвольного уровня.

Автор: princessRapunzel Размещён: 09.11.2017 03:03
Вопросы из категории :
32x32