Как объединить два списка диктовок, если значение ключа одинаково? - PullRequest
0 голосов
/ 26 апреля 2020

Учитывая два списка диктовок, как их можно объединить на основе значения определенного c ключа id?

#List of dicts1
players = [ {'age': '19 years 275 days',
  'birth': '24 July 2000',
  'birth_exact': 964396800000.0,
  'country': 'Ecuador',
  'first': 'Leonardo',
  'id': 74562.0,
  'isoCode': 'EC',
  'last': 'Campana',
  'loan': False,
  'name': 'Leonardo Campana',
  'nationalTeam': 'Ecuador',
  'playerId': 179304.0,
  'position': 'F',
  'positionInfo': 'Centre Striker',
  'season': 2019,
  'shirtNum': None},
 {'age': '24 years 186 days',
  'birth': '21 October 1995',
  'birth_exact': 814233600000.0,
  'country': 'Portugal',
  'first': 'Daniel',
  'id': 11362.0,
  'isoCode': 'PT',
  'last': 'Castelo Podence',
  'loan': False,
  'name': 'Daniel Podence',
  'nationalTeam': 'Portugal',
  'playerId': 180050.0,
  'position': 'M',
  'positionInfo': 'Left/Right Winger',
  'season': 2019,
  'shirtNum': 10.0}]

#List of dicts2
squad = [ {'id': 11362.0,
  'team': 'Arsenal',
  'team_id':1,
  'team_shortName': 'Arsenal'},
 {'id': 74562.0,
  'team': 'Wolverhampton Wanderers',
  'team_id': 38,
  'team_shortName': 'Wolves'}]

Я хочу объединить информацию в squad в players.

Я пробовал следующее:

p_sort = sorted(players, key=lambda k: k['id']) 
s_sort = sorted(squad, key=lambda k: k['id']) 
l3 = [{**u, **v} for u, v in zip_longest(p_sort, s_sort, fillvalue={})]
return l3

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

Ожидаемый результат:

l3 = [ {'age': '19 years 275 days',
  'birth': '24 July 2000',
  'birth_exact': 964396800000.0,
  'country': 'Ecuador',
  'first': 'Leonardo',
  'id': 74562.0,
  'isoCode': 'EC',
  'last': 'Campana',
  'loan': False,
  'name': 'Leonardo Campana',
  'nationalTeam': 'Ecuador',
  'playerId': 179304.0,
  'position': 'F',
  'positionInfo': 'Centre Striker',
  'season': 2019,
  'shirtNum': None,
  'team': 'Wolverhampton Wanderers',
  'team_id': 38,
  'team_shortName': 'Wolves'}},

 {'age': '24 years 186 days',
  'birth': '21 October 1995',
  'birth_exact': 814233600000.0,
  'country': 'Portugal',
  'first': 'Daniel',
  'id': 11362.0,
  'isoCode': 'PT',
  'last': 'Castelo Podence',
  'loan': False,
  'name': 'Daniel Podence',
  'nationalTeam': 'Portugal',
  'playerId': 180050.0,
  'position': 'M',
  'positionInfo': 'Left/Right Winger',
  'season': 2019,
  'shirtNum': 10.0},
  'team': 'Arsenal',
  'team_id': 1,
  'team_shortName': 'Arsenal'}]

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

Я удалил некоторые из ваших данных, чтобы уменьшить вывод - вы можете использовать 2 словаря, чтобы получить быстрый доступ к тому, что идентификатор в каком списке (отряды против игроков).

Вы l oop один раз над списком игроков и обновлять их, если они получили отряд с тем же ключом - вы также можете использовать дикты, чтобы утверждать, все ли квадраты получили информацию об игроке:

players = [ {'age': '19 years 275 days',
  'birth': '24 July 2000', 
  'id': 74562.0  },
 {'age': '24 years 186 days',
  'birth': '21 October 1995',
  'birth_exact': 814233600000.0,
  'id': 11362.0,}, 
  {'age': '24 years 186 days',
  'birth': '21 October 1995',
  'birth_exact': 814233600000.0,
  'id':42,}]

# fixed name
squads = [ {'id': 11362.0,
  'team': 'Arsenal',
  'team_id':1,
  'team_shortName': 'Arsenal'},
 {'id': 74562.0,
  'team': 'Wolverhampton Wanderers',
  'team_id': 38,
  'team_shortName': 'Wolves'},
  {'id': -3,
  'team': 'Wolverhampton Wanderers',
  'team_id': 38,
  'team_shortName': 'Wolves'}]

p_sort = sorted(players, key=lambda k: k['id']) 
s_sort = sorted(squads, key=lambda k: k['id']) 

keyed_players = {a["id"]:a for a in p_sort} # easier access for IN - check
keyed_squads = {a["id"]:a for a in s_sort}  # easier access for IN - check

# iterate players and modify them if squad info given, else printout info
for player in p_sort:
    if player["id"] in keyed_squads:
        player.update(keyed_squads[player["id"]])
    else:
        print("player", player["id"], "has no squad info")

print(p_sort)

# get squads without players
for s in keyed_squads:
    if s not in keyed_players:
        print("squad", s, "has no player info")

Вывод:

player 42 has no squad info

[{'age': '24 years 186 days', 'birth': '21 October 1995', 
  'birth_exact': 814233600000.0, 'id': 42}, 
 {'age': '24 years 186 days', 'birth': '21 October 1995', 
  'birth_exact': 814233600000.0, 'id': 11362.0, 
  'team': 'Arsenal', 'team_id': 1, 'team_shortName': 'Arsenal'}, 
 {'age': '19 years 275 days', 'birth': '24 July 2000', 'id': 74562.0, 
  'team': 'Wolverhampton Wanderers', 'team_id': 38, 'team_shortName': 'Wolves'}]

squad -3 has no player info

Код для конечно, содержит больше строк, чем ваша - но гораздо яснее, что и что делает - что может быть бонусом, если вы посмотрите на это через 4 недели.

1 голос
/ 26 апреля 2020

Попробуйте:

res = [{**x, **y}  for y in players for x in squad if x['id'] == y['id']]
d = [dict(sorted(d.items())) for d in res]

Вывод:

[{'age': '19 years 275 days', 'birth': '24 July 2000', 'birth_exact': 964396800000.0, 'country': 'Ecuador', 'first': 'Leonardo', 'id': 74562.0, 'isoCode': 'EC', 'last': 'Campana', 'loan': False, 'name': 'Leonardo Campana', 'nationalTeam': 'Ecuador', 'playerId': 179304.0, 'position': 'F', 'positionInfo': 'Centre Striker', 'season': 2019, 'shirtNum': None, 'team': 'Wolverhampton Wanderers', 'team_id': 38, 'team_shortName': 'Wolves'}, {'age': '24 years 186 days', 'birth': '21 October 1995', 'birth_exact': 814233600000.0, 'country': 'Portugal', 'first': 'Daniel', 'id': 11362.0, 'isoCode': 'PT', 'last': 'Castelo Podence', 'loan': False, 'name': 'Daniel Podence', 'nationalTeam': 'Portugal', 'playerId': 180050.0, 'position': 'M', 'positionInfo': 'Left/Right Winger', 'season': 2019, 'shirtNum': 10.0, 'team': 'Arsenal', 'team_id': 1, 'team_shortName': 'Arsenal'}]
...