Группировка и сортировка словаря и добавление значения ключа

У меня есть список словарей, который выглядит так

players = [{'Name': 'Player 1', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '9400'},{'Name': 'Player 2', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '8400'}, {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '7400'}, {'Name': 'Player 2', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '8400'}, {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '7400'}]

В этом списке словарей будут игроки с позициями QB, RB, WR, TE. Мне нужно перебрать список и сгруппировать каждый словарь по команде и позиции. Затем мне нужно отсортировать каждую должность по зарплате в порядке убывания. После того, как каждый словарь сгруппирован и отсортирован, мне нужно вернуться к списку и добавить ключ глубины и значение для позиции, в которой находится игрок.

Пример:

МИН РБ

[{'Name': 'Player 1', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '9400', 'Depth': 1,},{'Name': 'Player 2', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '8400', 'Depth': 2}, {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '7400', 'Depth': 3}]

должны быть окончательные результаты.

Мне нужно будет сделать это для каждой позиции - QB, RB, WR, TE. Двойных игроков нет, но у игроков может быть одинаковая зарплата, в этом случае глубина будет одинаковой для обоих игроков.

Вот что у меня есть на данный момент, но я не уверен, как разбить это дальше

players = sorted(players, key=itemgetter('Pos'))
position_groups = dict((key, list(value)) for key, value in itertools.groupby(players,key=itemgetter('Pos')))

Где ты застрял?

Dani Mesejo 11.12.2020 16:30

Вы смотрели itertools?

MetallimaX 11.12.2020 16:36

@DaniMesejo У меня есть список, сгруппированный по позициям, но затем мне нужно сгруппировать эти списки по командам.

Austin Johnson 11.12.2020 18:30
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
562
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если у вас нет проблем с библиотекой pandas, это будет простым решением вашей проблемы. Я не получил последнюю часть, относящуюся к глубине, но решение первой части должно быть таким:

import pandas as pd

players = [{'Name': 'Player 1', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '9400'},
           {'Name': 'Player 2', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '8400'},
           {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '7400'},
           {'Name': 'Player 2', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '8400'},
           {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '7400'}]

df_players = pd.DataFrame(players)
df_RBs = df_players[df_players.Pos == 'RB']
print(df_RBs[df_RBs.Team == 'MIN'])
Ответ принят как подходящий

IIUC, вы можете сделать следующее:

import pprint
from collections import defaultdict
from operator import itemgetter

players = [{'Name': 'Player 1', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '9400'},
           {'Name': 'Player 2', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '8400'},
           {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'MIN', 'Salary': '7400'},
           {'Name': 'Player 2', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '8400'},
           {'Name': 'Player 3', 'Pos': 'RB', 'Team': 'NYG', 'Salary': '7400'}]

team_and_position = itemgetter('Team', 'Pos')
salary = itemgetter('Salary')

# create groups of positions within a given team
groups = defaultdict(list)
for player in players:
    groups[team_and_position(player)].append(player)

# sort each group by salary in descending order
groups = {k: sorted(group, key=salary, reverse=True) for k, group in groups.items()}

# add depth value to each player
res = {k: [{**player, "Depth": depth} for depth, player in enumerate(group, 1)] for k, group in groups.items()}

# fetch MIN RB
vikings_rb = res[('MIN', 'RB')]

pprint.pprint(vikings_rb)

Выход

[{'Depth': 1, 'Name': 'Player 1', 'Pos': 'RB', 'Salary': '9400', 'Team': 'MIN'},
 {'Depth': 2, 'Name': 'Player 2', 'Pos': 'RB', 'Salary': '8400', 'Team': 'MIN'},
 {'Depth': 3, 'Name': 'Player 3', 'Pos': 'RB', 'Salary': '7400', 'Team': 'MIN'}]

Первый шаг — использовать группировку элементов списка по Team и Pos, для этого вы можете использовать defaultdict и itemgetter для извлечения значений ключей:

# create groups of positions within a given team
groups = defaultdict(list)
for player in players:
    groups[team_and_position(player)].append(player)

Второй шаг — отсортировать внутри каждой группы по зарплате в порядке убывания:

# sort each group by salary in descending order
groups = {k: sorted(group, key=salary, reverse=True) for k, group in groups.items()}

Второй шаг можно было бы сделать на месте, но я предпочитаю понимание словаря. Наконец, используйте enumerate (начиная с 1), чтобы добавить значение глубины в каждый словарь:

# add depth value to each player
res = {k: [{**player, "Depth": depth} for depth, player in enumerate(group, 1)] for k, group in groups.items()}

Опять же, это можно сделать на месте, выполнив следующие действия:

for group in groups.values():
    for depth, player in enumerate(group, 1):
        player['Depth'] = depth

ОБНОВЛЯТЬ

Если вы хотите получить всех игроков, просто сгладьте значения словаря:

# fetch ALL players
all_players = [player for group in res.values() for player in group]
pprint.pprint(all_players)

Выход

[{'Depth': 1, 'Name': 'Player 1', 'Pos': 'RB', 'Salary': '9400', 'Team': 'MIN'},
 {'Depth': 2, 'Name': 'Player 2', 'Pos': 'RB', 'Salary': '8400', 'Team': 'MIN'},
 {'Depth': 3, 'Name': 'Player 3', 'Pos': 'RB', 'Salary': '7400', 'Team': 'MIN'},
 {'Depth': 1, 'Name': 'Player 2', 'Pos': 'RB', 'Salary': '8400', 'Team': 'NYG'},
 {'Depth': 2, 'Name': 'Player 3', 'Pos': 'RB', 'Salary': '7400', 'Team': 'NYG'}]

После этого отсортируйте список all_players по любому заданному критерию.

Как я мог вернуть каждого игрока, как у вас vikings_rb = res[('Min','RB')], но all_players = # каждый игрок в исходном отформатированном списке

Austin Johnson 11.12.2020 19:01

@AustinJohnson В каком-то конкретном порядке?

Dani Mesejo 11.12.2020 19:02

Да просто как один список диктов с каждым игроком

Austin Johnson 11.12.2020 19:03

@AustinJohnson Обновлен ответ, чтобы получить всех игроков

Dani Mesejo 11.12.2020 19:06

Другие вопросы по теме