gpt4 book ai didi

python - Python中的联赛表-它不会将球队插入列表

转载 作者:太空宇宙 更新时间:2023-11-03 19:08:47 24 4
gpt4 key购买 nike

我需要为一个项目制作一个排行榜。必须有3个文件,其中2个文件包含1个类,最后一个文件用于运行程序。我已经完成了所有部分,但是当我调用添加团队的方法时,程序会添加名称,但不会将其插入团队列表(应该这样做)。当我尝试显示列表中的项目时,程序将显示错误消息,而不是显示实际团队。

我该如何解决?任何帮助将不胜感激。 :)

最佳答案

这里有几件事:


  当我尝试显示列表中的项目时,程序将显示:team.Team对象,位于0x000000000332A978,用于显示实际的团队。


用户类的默认显示类似于<team.Team object at 0x000000000332A978>。如果希望它显示不同的内容,则必须告诉Python您要显示的内容。为此有两个单独的功能:__repr__ and __str__。这个想法是第一个代表程序员,第二个代表用户。如果不需要两个不同的表示形式,只需定义__repr__,并在需要__str__时使用它。

因此,解决此问题的一种非常简单的方法是将其添加到Team类中:

def __repr__(self):
return 'Team("{}")'.format(self._name)


现在,如果先调用 league.addTeam('Dodgers'),然后调用 print(l._table),则将得到 [Team("Dodgers")]而不是 [<team.Team object at 0x000000000332A978>]

同时,这两种方法可能不是您想要的:

def removeTeam(self,team):
self._table.remove(team)
def returnPosition(self,team):
return self._table.index(team)


这些将删除或找到具有 Team对象的团队-不是名称,甚至不是从该名称创建的新 Team,而是对存储在 _table中的相同对象的引用。这并不是全部有用,您似乎只想用名称来称呼它们。

有两种方法可以解决此问题:您可以更改 Team,以便通过将此方法添加到类中来按名称而不是按对象标识进行比较:

def __eq__(self, other):
return self._name == other._name


这意味着如果您说 Team('Giants') == Team('Giants'),它将现在为true而不是False。即使第一支球队不在同一个联赛中,并且拥有不同的WL记录,依此类推(例如,像来自旧金山的棒球“巨人”与来自纽约的足球“巨人”),就Python而言有关,他们现在是同一支球队。当然,如果这不是您想要的,则可以编写任何其他更合适的 __eq__函数。

无论如何,如果您执行此操作, indexremove函数现在将能够找到具有相同名称的任何 Team,而不仅仅是完全相同的团队,因此:

def removeTeam(self,team_name):
self._table.remove(Team(team_name))
def returnPosition(self,team_name):
return self._table.index(Team(team_name))


如果您采用这种方式,则可能需要考虑定义所有 comparison methods,因此您可以例如对团队列表进行排序,然后按名称进行排序。

或者,您可以更改这些方法,以免它们无法基于相等性工作,例如,通过重新定义如下:

def removeTeam(self,team_name):
self._table = [team for team in self._table if team._name != team_name]
def returnPosition(self,team_name):
return [team._name for team in self._table].index(team_name)


要了解它们是如何工作的,如果您不习惯阅读列表推导,请将每一个推回等效循环中:

self._table = [team for team in self._table if team._name != team_name]

temp = []
for team in self._table:
if team._name != team_name:
temp.append(team)
self._table = temp


如果您逐步执行此操作,则 temp最终会列出表中每个团队的列表,但要删除的团队除外,然后用新的过滤后的团队替换旧的 self._table。 (写相同想法的另一种方法是使用 filter,如果您知道该函数。)

通常,创建新的过滤列表要比就地修改列表更好。有时出于性能原因而不执行此操作,有时最终变得非常复杂且难以理解,但通常推理起来既更快又更简单。同样,在适当位置修改列表会导致如下问题:

for i, value in enumerate(mylist):
if value == value_to_remove:
del mylist[i]


玩一会儿,您会发现它实际上不起作用。了解原因有点复杂,您可能不希望稍后再学习。解决该问题的通常技巧是遍历列表的副本……但是,一旦执行此操作,您将同时遇到最糟糕的过滤和最糟糕的就地删除。

第二个功能可能有点聪明,但让我们看一下:

def returnPosition(self,team_name):
return [team._name for team in self._table].index(team_name)


首先,我要创建一个与原始列表类似的列表,但这只是名称列表而不是团队对象列表。再次,让我们分解列表的理解:

temp = []
for team in self._table:
temp.append(team._name)


或尝试将其翻译成英语:这是表中每个团队的团队名称的列表。

现在,因为这是团队名称的列表,所以我可以使用 index(team_name)它将找到它。而且,由于两个列表的形状相同,所以我知道这也是在原始 team列表中使用的正确索引。

一个更简单的解决方案是将 _tableslistTeam更改为将名称映射到 dictTeam。这可能是最Python化的解决方案,它看起来比编写列表理解来执行简单操作要简单得多。 (它可能也是最有效的,但是除非您拥有一些真正的庞大联赛,否则这几乎没有关系。)然后,您甚至不需要 returnPosition即可。要做到这一点:

def __init__(self):
self._table={}
def addTeam(self,name):
self._table[name]=Team(name)
def removeTeam(self,team_name):
del self._table[team_name]
def returnPosition(self,team_name):
return team_name
def updateLeague(self,team1_name1,team_name2,score1,score2):
if score1>score2:
self._table[team_name1].win()
self._table[team_name2].loss()
elif score1==score2:
self._table[team_name1].draw()
self._table[team_name2].draw()
elif score1<score2:
self._table[team_name1].loss()
self._table[team_name2].win()


请注意,我已经定义 returnPosition只是返回团队名称本身作为位置。如果您考虑一下, dict密钥的使用方式与 list索引完全相同,因此这意味着有人为“旧” API编写的任何需要 returnPosition的代码仍可与“新” API一起使用。 (我可能不会尝试将其卖给分配了需要我们使用 returnPosition的问题的老师,但是对于一个实际的图书馆,我想让我的1.3用户更容易地迁移到2.0,我可能会。)

这仅需要其他一些更改。在 displayListsaveList中,您遍历 self._table.values()而不是 self._table;在 loadList中,将 self._table.append(team)更改为 self._table[a] = team。说到 loadList:您可能要考虑将那些局部变量从 abcd重命名为 namewinslossesdraws

其他一些评论:


正如kreativitea在评论中说的那样,您不应创建“私有”变量,然后在Python中添加不做任何事情的访问器方法。它只是隐藏了真实代码的样板,还有一个愚蠢的错字,您可能会犯错,这将花费您数小时的调试时间。只需具有名为 namewinslosses等的成员,然后直接访问它们即可。 (如果有人告诉您这是一种不好的风格,因为它不允许您将来在不更改接口的情况下替换实现,那么这仅适用于Java和C ++,不适用于Python。如果您需要替换实现,则只需阅读 @property。)
您不需要 print(""""""),很容易意外地误算了 "个字符的数量。 (特别是因为某些IDE实际上会对此感到困惑,并认为多行字符串永远不会结束。)只需执行 print()
while循环( while x!="q":)和内部 break中,您都具有相同的结束条件。您在两个地方都不需要它。要么将其更改为 while True:,要么摆脱 break(只需将 options("q")设为 print("Goodbye"),这样就不需要在循环内对它进行特殊处理)。
每当您有长链的 elif语句时,请考虑是否可以将其转换为短函数的 dict。在这种情况下,我不确定这是个好主意,但始终值得思考并做出明确的决定。


最后一个主意如下所示:

def addTeam():
name=input("Enter the name of the team:")
l.addTeam(name)
def removeTeam():
teamToRemove=input("Enter the name of the team you want to remove:")
l.removeTeam(teamToRemove)
def recordGame():
team1=input("What is the name of the team?")
ans1=int(input("Enter the number of goals for the first team:"))
team2=input("What is the name of the team?")
ans2=int(input("Enter the number of goals for the second time:"))
l.updateLeague(team1,team2,ans1,ans2)
optionsdict = {
"a": addTeam,
"d": l.displayList,
"s": l.saveList,
"l": l.loadList,
"r": removeTeam,
"rec": recordGame,
}
def options(x):
func = optionsdict.get(x)
if func:
func()


就像我说的,我不确定在这种情况下它是否更清晰,但是值得考虑。

关于python - Python中的联赛表-它不会将球队插入列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13750909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com