Как включить в список словарей? - PullRequest
0 голосов
/ 05 мая 2018

Предупреждение новичка - но потратил несколько часов на это и просто не могу понять - у меня есть этот список:

players = [{'name': 'John', 'points': '27', 'Played': '6'},
{'name': 'Emil', 'points': '43', 'Played' : '13'},
{'name': 'Susan', 'points': '11', 'Played': '2'},
{'name': 'Peter', 'points': '4', 'Played': '3'}]

Я хотел бы сказать:

players["John"]["score"]=newScore
players["john"]["Played"] = players["john"]["Played"]+1

Этот список представляет собой список объектов, где имя является первичным ключом, а затем параметры для каждого объекта.

Но конечно, что не работает, я могу прикоснуться к элементам, выполнив:

print (players[0]["score"])

, и тогда будет напечатан счет Джона, но с этим способом мне нужно будет пройти через всех игроков [x], чтобы сначала сравнить, если имя то же самое, а затем я могу получить к нему доступ, это просто не кажется таким питоном для меня.

Как бы вы поступили так по-питонски?

Ответы [ 5 ]

0 голосов
/ 05 мая 2018

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

>>> new_data_struct_players = {}

>>> for player in players:
...    new_data_struct_players[player['name']] = {
...        'points': int(player['points']),  # make it number (int)
...        'Played': int(player['points'])   # make it number too
...    }

>>> print(new_data_struct_players['John'])
{'points': '27', 'Played': 27}

print(new_data_struct_players['John']['points'])
27
0 голосов
/ 05 мая 2018

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

class Row:
   def __init__(self, row):
      self.row = row
   def __setitem__(self, _t, _val):
      self.row[_t] = str(_val)
   def __getitem__(self, _stat):
      return int(self.row[_stat])
   def __repr__(self):
      return '{}({})'.format(self.__class__.__name__, str(self.row))

class Players:
   def __init__(self, data={}):
      self.data = {i['name']:Row(i) for i in data}
   def __getitem__(self, name):
      return self.data[name]
   def __setitem__(self, _name, _data):
      self.data[_name] = Row(_data)
   def __repr__(self):
      return '{}({})'.format(self.__class__.__name__, str(self.data))

players = [{'points': '27', 'name': 'John', 'Played': '6'}, {'points': '43', 'name': 'Emil', 'Played': '13'}, {'points': '11', 'name': 'Susan', 'Played': '2'}, {'points': '4', 'name': 'Peter', 'Played': '3'}]
d = Players(players)
d['John']['points'] = 30
d["John"]["Played"] = d["John"]["Played"]+1
print(d['John'])
d['Bob'] = {'points': '2', 'Played': '5'}

Выход:

Row({'points': '30', 'name': 'John', 'Played': '7'})
0 голосов
/ 05 мая 2018

Измените структуру данных, если ключом является Name, просто:

players_dict = {d['Name']: d for d in players}

позволит вам сделать:

players_dict["John"]["score"] = new_score
0 голосов
/ 05 мая 2018

По моему мнению, список словарей неэффективен и не является рекомендуемым решением для хранения структурированных данных такого рода.

Вы можете использовать collections.namedtuple из стандартной библиотеки, но я предпочитаю стороннюю библиотеку pandas, которая напрямую принимает список словарей:

import pandas as pd

players = [{'name': 'John', 'points': '27', 'Played': '6'},
           {'name': 'Emil', 'points': '43', 'Played' : '13'},
           {'name': 'Susan', 'points': '11', 'Played': '2'},
           {'name': 'Peter', 'points': '4', 'Played': '3'}]

df = pd.DataFrame(players)

print(df)

  Played   name points
0      6   John     27
1     13   Emil     43
2      2  Susan     11
3      3  Peter      4

Затем вы можете выполнять манипуляции, используя pandas API:

# Add a new column and specify value for a given name
df['Score'] = 0
df.loc[df['name'] == 'John', 'Score'] = 1

# Add 1 to John played
df.loc[df['name'] == 'John', 'Played'] += 1
0 голосов
/ 05 мая 2018

Если вам нужен доступ к этим диктовкам по имени игрока, лучше адаптировать формат ваших данных к этой необходимости.

например:.

playersDict = {o['name']: o for o in players}

Теперь вы можете использовать playersDict, как в вашем примере:

>>> playersDict['John']['Played']
'6'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...