Условное ранжирование данных из списков, вложенных в словари

Я начал изучать Python с курса cs50x и добрался до своего первого собственного проекта, Discordbot, предоставляющего выбор карты для нашей команды cs:go. до сих пор я завершил сбор данных, и теперь у меня есть словарь, заполненный словарем для каждой карты, заполненный списками для различных статистических данных:

mapdata = [
    ('de_inferno', {'winrate': [54, 52, 55, 29, 51], 'matches': [52, 56, 22, 21, 71], 'wins': [28, 29, 12, 6, 36], 'twins': [26, 26, 11, 8, 36], 'ctwins': [29, 32, 12, 11, 38], 'total': [5, 222, 50, 48, 54]}),
    ('de_nuke', {'winrate': [60, 65, 65, 71, 54], 'matches': [30, 34, 20, 14, 35], 'wins': [18, 22, 13, 10, 19], 'twins': [14, 16, 10, 8, 15], 'ctwins': [18, 21, 13, 9, 21], 'total': [5, 133, 61, 47, 61]}),
    ('de_dust2', {'winrate': [47, 41, 36, 33, 50], 'matches': [30, 34, 11, 9, 32], 'wins': [14, 14, 4, 3, 16], 'twins': [14, 15, 4, 4, 17], 'ctwins': [16, 17, 6, 5, 17], 'total': [5, 116, 43, 46, 52]}),
    ('de_overpass', {'winrate': [54, 64, 14, 82, 30], 'matches': [26, 25, 7, 11, 27], 'wins': [14, 16, 1, 9, 8], 'twins': [12, 11, 3, 6, 10], 'ctwins': [15, 16, 3, 6, 15], 'total': [5, 96, 50, 43, 57]}),
    ('de_vertigo', {'winrate': [82, 63, 75, 75, 55], 'matches': [11, 8, 4, 4, 11], 'wins': [9, 5, 3, 3, 6], 'twins': [5, 4, 2, 3, 5], 'ctwins': [7, 4, 3, 2, 6], 'total': [5, 38, 68, 50, 57]}),
    ('de_mirage', {'winrate': [60, 50, 0, 33, 63], 'matches': [5, 2, 1, 3, 8], 'wins': [3, 1, 0, 1, 5], 'twins': [2, 0, 0, 1, 3], 'ctwins': [3, 1, 0, 2, 6], 'total': [5, 19, 52, 31, 63]}),
    ('de_ancient', {'winrate': [33, 50, 43], 'matches': [3, 2, 7], 'wins': [1, 1, 3], 'twins': [1, 1, 2], 'ctwins': [1, 1, 4], 'total': [3, 12, 41, 33, 50]}),
    ('de_anubis', {'winrate': [0, 50, 50, 67], 'matches': [3, 4, 2, 6], 'wins': [0, 2, 1, 4], 'twins': [2, 2, 1, 3], 'ctwins': [1, 2, 1, 3], 'total': [4, 15, 46, 53, 46]}),
    ('de_cache', {'winrate': [0, 0, 38], 'matches': [2, 2, 8], 'wins': [0, 0, 3], 'twins': [0, 1, 4], 'ctwins': [1, 1, 4], 'total': [3, 12, 25, 41, 50]}),
    ('de_tuscan', {'winrate': [100], 'matches': [1], 'wins': [1], 'twins': [1], 'ctwins': [0], 'total': [1, 1, 100, 100, 0]}),
    ('de_train', {'winrate': [33], 'matches': [3], 'wins': [1], 'twins': [1], 'ctwins': [2], 'total': [1, 3, 33, 33, 66]})
]

последний список в каждом словаре содержит первую часть анализа, в которой указаны игроки, сыгравшие на карте, общее количество игр, общий процент побед, процент побед t и процент побед ct. пока мои результаты из этого словаря работают, но я хотел бы добавить условие для вырезания результатов с помощью «Игроки, которые играли на карту» <= 3

sortedlist = sorted(mapdata, key=lambda x: (mapdata[x]["total"][2]), reverse=True)

предоставляет мне правильный порядок карт, отсортированных по винрейту в общем списке. Теперь я мог искать соответствующие значения для каждой карты и объединять 2 списка, но я почти уверен, что функция сортировки также может мне помочь. я не могу понять ключ = lambda x: часть. насколько я понимаю, mapdata[x] сортируется по рейтингу (mapdata[x]["total"][2]). как вывести эти значения?

с другой стороны, я хотел бы принимать в рейтинге только те карты, в которые играло большинство игроков, поэтому (mapdata[x]["total"][0]) должно быть 4 или больше (это число изменится если одновременно не будет 5 игроков). это может быть достигнуто путем клонирования и удаления dict заранее, но я чувствую, что может быть способ сделать это и в отсортированной функции.

Спасибо за помощь! в качестве дополнения: я открыт для другой структуры данных, я уже переключил ее с csv на dict, и я до сих пор не уверен, что словарь для каждой карты - это путь (но это помогло мне со сбором данных и пригодится для дальнейшего анализа)

Итак, учитывая ваш стартовый список, вам нужны данные карты (только название карты?) для карт, у которых mapdata[x]["total"][0] >= 4 упорядочен по mapdata[x]["total"][2]?

JonSG 12.02.2023 23:26

да! в лучшем случае это будет имя карты: значение [2] в качестве вывода, но я могу найти 2 позже

Sven 12.02.2023 23:34
Почему в 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
2
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы хотите посмотреть, как filtered используется в тандеме с sorted. Первый, чтобы получить только интересующие карты, а второй, чтобы расположить их в хорошем порядке.

После этого вы можете создать словарь поиска или, если вам просто нужен список кортежей, вы также можете это сделать...

mapdata = [
    ('de_inferno', {'winrate': [54, 52, 55, 29, 51], 'matches': [52, 56, 22, 21, 71], 'wins': [28, 29, 12, 6, 36], 'twins': [26, 26, 11, 8, 36], 'ctwins': [29, 32, 12, 11, 38], 'total': [5, 222, 50, 48, 54]}),
    ('de_nuke', {'winrate': [60, 65, 65, 71, 54], 'matches': [30, 34, 20, 14, 35], 'wins': [18, 22, 13, 10, 19], 'twins': [14, 16, 10, 8, 15], 'ctwins': [18, 21, 13, 9, 21], 'total': [5, 133, 61, 47, 61]}),
    ('de_dust2', {'winrate': [47, 41, 36, 33, 50], 'matches': [30, 34, 11, 9, 32], 'wins': [14, 14, 4, 3, 16], 'twins': [14, 15, 4, 4, 17], 'ctwins': [16, 17, 6, 5, 17], 'total': [5, 116, 43, 46, 52]}),
    ('de_overpass', {'winrate': [54, 64, 14, 82, 30], 'matches': [26, 25, 7, 11, 27], 'wins': [14, 16, 1, 9, 8], 'twins': [12, 11, 3, 6, 10], 'ctwins': [15, 16, 3, 6, 15], 'total': [5, 96, 50, 43, 57]}),
    ('de_vertigo', {'winrate': [82, 63, 75, 75, 55], 'matches': [11, 8, 4, 4, 11], 'wins': [9, 5, 3, 3, 6], 'twins': [5, 4, 2, 3, 5], 'ctwins': [7, 4, 3, 2, 6], 'total': [5, 38, 68, 50, 57]}),
    ('de_mirage', {'winrate': [60, 50, 0, 33, 63], 'matches': [5, 2, 1, 3, 8], 'wins': [3, 1, 0, 1, 5], 'twins': [2, 0, 0, 1, 3], 'ctwins': [3, 1, 0, 2, 6], 'total': [5, 19, 52, 31, 63]}),
    ('de_ancient', {'winrate': [33, 50, 43], 'matches': [3, 2, 7], 'wins': [1, 1, 3], 'twins': [1, 1, 2], 'ctwins': [1, 1, 4], 'total': [3, 12, 41, 33, 50]}),
    ('de_anubis', {'winrate': [0, 50, 50, 67], 'matches': [3, 4, 2, 6], 'wins': [0, 2, 1, 4], 'twins': [2, 2, 1, 3], 'ctwins': [1, 2, 1, 3], 'total': [4, 15, 46, 53, 46]}),
    ('de_cache', {'winrate': [0, 0, 38], 'matches': [2, 2, 8], 'wins': [0, 0, 3], 'twins': [0, 1, 4], 'ctwins': [1, 1, 4], 'total': [3, 12, 25, 41, 50]}),
    ('de_tuscan', {'winrate': [100], 'matches': [1], 'wins': [1], 'twins': [1], 'ctwins': [0], 'total': [1, 1, 100, 100, 0]}),
    ('de_train', {'winrate': [33], 'matches': [3], 'wins': [1], 'twins': [1], 'ctwins': [2], 'total': [1, 3, 33, 33, 66]})
]

##----------------------------
## Only maps played by 4 or more players
##----------------------------
foo = filter(lambda item: item[1]["total"][0] >= 4, mapdata)
##----------------------------

##----------------------------
## Fillter maps from above orderd by ranking
##----------------------------
bar = sorted(foo, key=lambda item: item[1]["total"][2], reverse=True)
##----------------------------

##----------------------------
## Reshape your ordered data into collection of tuples
##----------------------------
baz = map(lambda item: (item[0], item[1]["total"][2]), bar)
baz = list(baz) # map returns an iterator that we would consume to do the first print so capture it as a list here
##----------------------------

##----------------------------
## Printing your data as a list or dictionary
##----------------------------
print("\nUsing filter/sorted/map:")
print(f"\tAs a list (of tuples): { baz } ")
print(f"\tAs a dictionary: { dict(baz) } ")
##----------------------------

##----------------------------
## Finally, if you like comprehensions, you could do this
## for the same effect. Note that this sorts then filters where in
## the first case we filtered then sorted.
##----------------------------
baz = [
    (item[0], item[1]["total"][2])
    for item
    in sorted(mapdata, key=lambda item: item[1]["total"][2], reverse=True)
    if item[1]["total"][0] >= 4
]
print("\nUsing comprehension:")
print(f"\tAs a list (of tuples): { list(baz) } ")
print(f"\tAs a dictionary: { dict(baz) } ")
##----------------------------

Это должно дать вам:

Using filter/sorted/map:
        As a list (of tuples): [('de_vertigo', 68), ('de_nuke', 61), ('de_mirage', 52), ('de_inferno', 50), ('de_overpass', 50), ('de_anubis', 46), ('de_dust2', 43)]
        As a dictionary: {'de_vertigo': 68, 'de_nuke': 61, 'de_mirage': 52, 'de_inferno': 50, 'de_overpass': 50, 'de_anubis': 46, 'de_dust2': 43}

Using comprehension:
        As a list (of tuples): [('de_vertigo', 68), ('de_nuke', 61), ('de_mirage', 52), ('de_inferno', 50), ('de_overpass', 50), ('de_anubis', 46), ('de_dust2', 43)]
        As a dictionary: {'de_vertigo': 68, 'de_nuke': 61, 'de_mirage': 52, 'de_inferno': 50, 'de_overpass': 50, 'de_anubis': 46, 'de_dust2': 43}

привет, спасибо за ваши усилия! я попробовал фильтр, а затем отсортированный, но выдает ошибку типа для code foo = filter (элемент лямбда: элемент [1] ['total'] [0] >= 4, mapdata) ~~~~~~~^ ^^^^^^^^ (отмечено "всего") code также я не совсем понимаю, как mapdata["name"] превращается в item[1], а также почему источник для filter/sorted помещается после/впереди параметров, но сейчас я проверяю документацию. кроме того, есть ли подходящий редактор для комментирования? :D

Sven 13.02.2023 02:52

@Sven Если вам так удобнее, foo = list(filter(lambda item: item[1]["total"][0] >= 4, mapdata)) эквивалентно foo = [item for item in mapdata if item[1]['total'] >= 4]

Stef 13.02.2023 10:33

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

JonSG 13.02.2023 13:03

@Steff, да, так мне становится намного понятнее! у JonSG типа ошибка была на моей стороне. скопировал данные карты из терминала, но в моем коде они присутствовали в виде словаря. просто преобразовал его в список, и он отлично работает

Sven 13.02.2023 16:58

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