如何索引到词典列表?

时间:2018-05-05 14:51:14

标签: python python-3.x dictionary

新手提醒 - 但现在已经花了几个小时在这上面而且无法弄明白 - 我有这个清单:

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

此列表表示对象列表,其中名称是主键,然后是每个对象的theres参数。

但是当然没有效果,我能够通过以下方式触摸元素:

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

然后这将打印出Johns得分好,但是通过这种方式我需要通过所有玩家[x]首先比较一下,如果名字是相同的,然后我可以访问它,它只是似乎没有这么蟒蛇对我来说。

你会怎样以pythonic方式进行此操作?

5 个答案:

答案 0 :(得分:7)

更改您的数据结构,如果Name是关键,则只需:

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

允许你这样做:

players_dict["John"]["score"] = new_score

答案 1 :(得分:2)

如果您需要按播放器名称访问这些字符串,最好根据需要调整数据格式。

E.g:

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

现在您可以按照示例中的playersDict进行操作:

>>> playersDict['John']['Played']
'6'

答案 2 :(得分:1)

在我看来,词典列表效率低下,而不是建议使用此类结构化数据的解决方案。

您可以使用标准库中的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

答案 3 :(得分:1)

您可以为此创建新的结构数据。 e.g。

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

答案 4 :(得分:0)

您可以使用可以提供指定的专用更新方法的类来包装当前数据,而不必更改原始数据的整个结构:

?- setof(X, Y^foo(Y, X), Result).
Result = [a, b].

输出:

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'}