如何将Python字典从列表中分离出来进行比较?
我有一个Python函数,它以玩家的名字和分数作为参数,并确定这是否是玩家的最高分数。它通过将参数与搁置对象进行比较来实现 架子上应该只存储每个玩家的高分;例如,对于一个叫“乔”的人,不应该有分数 不幸的是,我不知道如何将dict从dict列表(shelf)中分离出来,以便与传入的播放器dict进行比较 这是我的密码:如何将Python字典从列表中分离出来进行比较?,python,list,dictionary,shelve,Python,List,Dictionary,Shelve,我有一个Python函数,它以玩家的名字和分数作为参数,并确定这是否是玩家的最高分数。它通过将参数与搁置对象进行比较来实现 架子上应该只存储每个玩家的高分;例如,对于一个叫“乔”的人,不应该有分数 不幸的是,我不知道如何将dict从dict列表(shelf)中分离出来,以便与传入的播放器dict进行比较 这是我的密码: import shelve import os def highscore(player_name, player_score): """ Function
import shelve
import os
def highscore(player_name, player_score):
"""
Function to return the high score from our
persistent storage of score records for a given
person.
"""
# Get our working directory
working_dir = os.getcwd()
# Create our shelf object for a player
highscore_fn = os.path.join(working_dir, 'highscore.shelve')
# Set our player info
player = {'name': player_name, 'score': player_score}
with shelve.open(highscore_fn, writeback=True) as shelf:
# Check if any records exist in the shelf
if len(shelf) == 0:
# Assign the shelf to an empty list
shelf['player_data'] = []
# Append player data to shelf
shelf['player_data'].append(player)
# Current high score for player
high_score = player.get('score')
else:
# Loop through our player data list
for data in shelf['player_data']:
# Check to see if we have data for a player
if player['name'] in data['name']:
existing_record = data
# Compare the player's new score against previous score
if player.get('score') > existing_record.get('score'):
high_score = player.get('score')
# Update our record for the player
existing_record.update(player)
else:
high_score = existing_record.get('score')
else:
high_score = player.get('score')
shelf['player_data'].append(player)
# Return the high score
return high_score
任何提示都将不胜感激 如果您没有其他理由使用dict列表,那么仅使用dict of dict(甚至是简单的dict)将大大简化您的代码。假设你的架子看起来像
{
"user_data": {
"joe": {"score": 2999, "name":"joe"},
"walt": {"score": 1784, "name":"walt"},
"bunny": {"score": 87441, "name":"bunny"},
# etc
},
}
那么您的代码将如下所示:
player = {'name': player_name, 'score': player_score}
high_score = player_score
with shelve.open(highscore_fn, writeback=True) as shelf:
user_data = shelf["user_data"]
# Check if any records exist in the shelf
found = user_data.get(player_name)
if found:
if found["score"] < player_score:
user_data[player_name] = player
else:
high_score = found["score"]
else:
user_data[player_name] = player
shelf["user_data"] = user_data
return high_score
=>您的代码:
high_score = player_score
with shelve.open(highscore_fn, writeback=True) as shelf:
# Check if any records exist in the shelf
found = shelf.get(player_name, 0)
if found > player_score:
high_score = found
else:
shelf[player_name] = player_score
return player_score
编辑:2.7.3中的以下代码JustWorks(tm):
# scores.py
import shelve
DATA = {
"user_data": {
"joe": {"score": 2999, "name":"joe"},
"walt": {"score": 1784, "name":"walt"},
"bunny": {"score": 87441, "name":"bunny"},
# etc
},
}
class Score(object):
def __init__(self, path):
self.path = path
def init_data(self, data):
shelf = shelve.open(self.path)
shelf["user_data"] = data["user_data"]
shelf.close()
def read_data(self):
d = {}
shelf = shelve.open(self.path)
d["user_data"] = shelf["user_data"]
shelf.close()
return d
def highscore(self, name, score):
player = {'name': name, 'score': score}
high_score = score
shelf = shelve.open(self.path)
user_data = shelf["user_data"]
found = user_data.get(name)
if found:
if found["score"] < score:
user_data[name] = player
else:
high_score = found["score"]
else:
user_data[name] = player
shelf["user_data"] = user_data
shelf.sync()
shelf.close()
return high_score
>>> import scores
>>> s = scores.Score("scores.dat")
>>> s.init_data(scores.DATA)
>>> s.read_data()
{'user_data': {'walt': {'score': 1784, 'name': 'walt'}, 'joe': {'score': 2999, 'name': 'joe'}, 'bunny': {'score': 87441, 'name': 'bunny'}}}
>>> s.highscore("walt", 10000)
10000
>>> s.read_data()
{'user_data': {'walt': {'score': 10000, 'name': 'walt'}, 'joe': {'score': 2999, 'name': 'joe'}, 'bunny': {'score': 87441, 'name': 'bunny'}}}
#scores.py
进口货架
数据={
“用户数据”:{
“乔”:{“分数”:2999,“姓名”:“乔”},
“沃尔特”:{“分数”:1784,“名字”:“沃尔特”},
“兔子”:{“分数”:87441,“名字”:“兔子”},
#等
},
}
班级成绩(对象):
定义初始化(自身,路径):
self.path=path
def初始数据(自身,数据):
shelf=shelve.open(self.path)
工具架[“用户数据”]=数据[“用户数据”]
关闭
def读取_数据(自身):
d={}
shelf=shelve.open(self.path)
d[“用户数据”]=工具架[“用户数据”]
关闭
返回d
def高分(自我、姓名、分数):
玩家={'name':name,'score':score}
高分=分数
shelf=shelve.open(self.path)
用户数据=工具架[“用户数据”]
found=user\u data.get(名称)
如果发现:
如果找到[“分数”]<分数:
用户_数据[名称]=播放器
其他:
高分=找到[“分数”]
其他:
用户_数据[名称]=播放器
工具架[“用户数据”]=用户数据
shelf.sync()
关闭
返回高分
>>>输入分数
>>>s=分数.Score(“分数.dat”)
>>>s.init_数据(分数数据)
>>>美国read_数据()
{'user_data':{'walt':{'score':1784,'name':'walt'},'joe':{'score':2999,'name':'joe'},'bunny':{'score':87441,'name':'bunny'}
>>>s.highscore(“沃尔特”,10000)
10000
>>>美国read_数据()
{'user_data':{'walt':{'score':10000,'name':'walt'},'joe':{'score':2999,'name':'joe'},'bunny':{'score':87441,'name':'bunny'}
编辑以下是解决我问题的重构代码:
import shelve
import os
def highscore(name, score):
"""
Function to return the high score from our
persistent storage of score records for a given
person.
"""
# Get our working directory
working_dir = os.getcwd()
# Create our shelf object for a player
highscore_fn = os.path.join(working_dir, 'highscore.shelve')
# Open our shelf
with shelve.open(highscore_fn, writeback=True) as shelf:
# Check if player exists in shelf
if name in shelf:
# Check if score is greater than existing score
if score > shelf[name]:
# Assign our new high score
high_score = score
# Assign the value of player to our shelf
shelf[name] = score
else:
# Existing high score stands for player
high_score = shelf[name]
else:
# Assign the player to the shelf
shelf[name] = score
# Assign the high score to the player score
high_score = score
return high_score
我和你的剧本玩了一点。它很好用,但当我查看架子上的东西时,我发现:
{ 'player_data' : [ { 'score': 10, 'name': 'joe' }, { 'score': 5, 'name': 'jim'} ] }
它有一个字典(书架本身),其中包含一个目录列表,而目录列表又只有两个属性
在你的代码中,很明显你想要的只是一个玩家的属性(这里是[高分])(这里是一个名字)
我的建议是重写它,除非搁置的格式是公共API的一部分,以便搁置成为:
{ 'joe': 10, 'jim' : 5 }
player = {'name': player_name, 'score': player_score}
with shelve.open(highscore_fn) as shelf:
high_score = shelf[player_name] if shelf.has_key(player_name) else None
if (high_score is None) or (high_score < player_score):
high_score = player_score
shelf[player_name] = high_score
shelf.close()
return high_score
或者,如果以后要为每个玩家添加其他属性:
{ 'joe': { 'score': 10}, 'jim' : { 'score': 5} }
这样,一切都会变成:
{ 'joe': 10, 'jim' : 5 }
player = {'name': player_name, 'score': player_score}
with shelve.open(highscore_fn) as shelf:
high_score = shelf[player_name] if shelf.has_key(player_name) else None
if (high_score is None) or (high_score < player_score):
high_score = player_score
shelf[player_name] = high_score
shelf.close()
return high_score
player={'name':player_name,'score':player_score}
带搁板。打开(高分)作为搁板:
high_score=架子[player_name],如果架子上有_键(player_name),否则无
如果(高分为无)或(高分<球员分数):
高分=球员得分
架子[玩家姓名]=高分
关闭
返回高分
这只是bruno desthuilliers答案的一个微小变化,但我测试了id和:
- 它正确地保留并显示每个用户的较高分数
- 只保留较高分数的版本不需要
,因为所更改的只是工具架的顶层元素writeback=true
os.getcwd()
要计算应用程序数据的路径-“当前工作目录”不是指“您的代码文件所在的目录”,而是指“用户启动程序时所在的目录”(假设部分代码没有将其更改为其他任何内容…).你的书架上除了player\u data
dicts列表之外还有其他对象吗?因此,这不是我所需要的,尽管它让我朝着正确的方向思考。如果为同一名玩家输入了后续分数,则不会存储该玩家的高分。@PatrickBeeson:第一个示例中确实有一个输入错误和一个缺失。FWIW我不知道您正在使用哪个Python版本,但在我这里的版本(2.7.3)上,带有shelve.open()
会引发“AttributeError:DbfilenameShelf实例没有属性‘exit’”。