我有一个Python函数,它将玩家的名字和分数作为参数,并确定这是否是玩家的最高分。它是通过比较搁置对象的参数来实现的。
搁架应该只存储每个玩家的高分;对于名为" Joe"的人来说,不应该得分。例如。
不幸的是,我无法弄清楚如何将dict与dicts(shelf)列表隔离,以便与传入的玩家dict进行比较。
这是我的代码:
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
任何提示都将不胜感激!
答案 0 :(得分:1)
如果您没有其他理由使用词典列表,只需使用词典(甚至是简单的词典)就可以大大简化您的代码。假设你的架子看起来像
{
"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
请注意,如果书架只包含&#34; user_data&#34;,您可以摆脱此级别并直接将您的dicts存储在书架本身。此外,如果你只有得分保存,你可以把你的词典转换成一个简单的词典,即:
=&GT;你的架子:
{
"joe": : 2999,
"walt": 1784,
"bunny": 87441,
# etc
}
=&GT;你的代码:
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
编辑:以下代码JustWorks(tm)on 2.7.3:
# 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'}}}
答案 1 :(得分:0)
已编辑以下是解决我问题的重构代码:
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
答案 2 :(得分:0)
我用你的剧本玩了一点。它工作正常,但当我看到货架上的东西时,我发现:
{ 'player_data' : [ { 'score': 10, 'name': 'joe' }, { 'score': 5, 'name': 'jim'} ] }
它是一个字典(搁置本身),其中包含一个dicts列表,而该列表又只有2个属性。
在你的代码中很明显,你想要的只是一个玩家的属性(这里是[高]得分)(这里是一个名字)。
我的建议是重写它,除非搁架的格式是公共API的一部分,以便搁置成为:
{ 'joe': 10, 'jim' : 5 }
或者如果您以后想要为每个玩家添加其他属性:
{ 'joe': { 'score': 10}, 'jim' : { 'score': 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
这只是bruno desthuilliers答案的一个细微变化,但我测试了id和:
writeback=true
,因为更改的内容只是货架的顶级元素