2014-01-22 28 views
1

我有一个看起来像这样的列表:在列表的列表更改值有效

[['B Borg', '3', '3', '1.0'], ['F Perry', '7', '8', '0.875'], ['R Nadal', '3', '5', '0.6']] 

我想选择的这些网球选手2用户播放其中随机选择赢家模拟网球比赛。所以如果我选择B Borg和F Perry相遇,B Borg随机获胜。最终的结果应该是这样的:

[['B Borg', '4', '4', '1.0'], ['F Perry', '7', '9', '0.875'], ['R Nadal', '3', '5', '0.6']] 

在列表中的第一个元素是名字,第二个是比赛赢了,第三个是总玩游戏,第四就是胜率。

有没有“干净”的方式来做到这一点?我试过使用多个if-elif-else块。确定它的作品,但它的很多文字。

+2

您能不能告诉那些如果,ELIF - 你说的块? – mhlester

+2

这可能是学习类的好时机 – goncalopp

+1

你的数据结构至少应该是一个字典(可能是一个对象),并且不应该仅仅存储计算胜利百分比。它是一种便宜的操作,可能会与实际数据不同步。 – 2014-01-22 23:27:19

回答

3

使用类!

class TennisPlayer(object): 
    def __init__(self,name,wins=0,games_played=0,win_pct=None): 
     self.name = name 
     self.wins = wins 
     self.games_played = games_played 

     # Note that although I do take win_pct as a parameter, I never use 
     # it anywhere. This trick may be useful for you if you end up maintaining 
     # code someone else has written and don't need part of their data 
     # structure anymore, but don't feel like refactoring code is worth the time 

    @property 
    def win_pct(self): 
     return self.wins/self.games_played 

    # as per lanzz, the @property token basically makes this a function that can 
    # be called like an instance variable. 
    # 
    # >>> player = TennisPlayer("Foo Bar",2,3) # 2 wins 1 loss 
    # >>> player.win_pct 
    # 0.6666666666666666 
    # 
    # You could probably make this prettier using string formatting. 
    # Something like return "{:.2f}%".format(self.wins/self.games_played*100) 
    # but it will make data manipulation much harder. Consider writing 
    # a TennisPlayer.print_stats() function that will just pretty print 
    # all the stats to stdout 

    def win_game(self,other): 
     self.games_played += 1 
     self.wins += 1 
     other.games_played +=1 

lst = [['B Borg', '3', '3', '1.0'], ['F Perry', '7', '8', '0.875'], ['R Nadal', '3', '5', '0.6']] 

tennisplayers = [TennisPlayer(*player) for player in lst] 

# randomly choose B Borg (tennisplayers[0]) and F Perry (tennisplayers[1]) 

tennisplayers[0].win_game(tennisplayers[1]) 

有这么多的实现,你可以想象。这(在我看来,在任何情况下)最好的是,也能实现一个TennisMatch类这样:

class TennisMatch(object): 
    def __init__(self,player1,player2): 
     if type(player1) == list: 
      # implement special handlers for doubles games 
     else: 
      self.player1 = player1 
      self.player2 = player2 

    def play_match(self): 
     # do some stuff here 
     # to determine who wins and 
     # who goes crying to mommy 
     for player in [player1,player2]: 
      if player == winner: player.wins += 1 
      player.games_played += 1 

然后你就可以忽略def win_game我放在TennisPlayer类,因为它实际上只是一个糟糕实施的制定者。这效果更好。

+0

'TennisPlayer.win_pct'应该是一个方法或'@属性'。 – lanzz

+0

我承认我对'@财产'的理解与我对量子力学的理解大致相同。你可以把我连到一个很酷的地方吗? –

2

带班另一种解决方案(基本相同adsmith的,但我已经打字,所以很好哦。)

import random 

class Player: 
    def __init__(self, name): 
     self.name = name 
     self.wins = 0 
     self.games = 0 
    def win(self): 
     self.wins += 1 
     self.games += 1 
    def lose(self): 
     self.games += 1 
    def __str__(self): 
     win_pct = self.wins/self.games 
     return '{:10} {:10} {:10} {:10.2}'.format(self.name, self.wins, self.games, win_pct) 

def play_game(p1, p2): 
    winner, loser = random.sample([p1, p2], 2) 
    winner.win() 
    loser.lose() 

players = [Player(name) for name in ['B Borg', 'F Perry', 'R Nadal']] 

for _ in range(20): 
    play_game(*random.sample(players, 2)) 
for player in players: 
    print(player) 

结果举例:

B Borg    7   15  0.47 
F Perry    7   14  0.5 
R Nadal    6   11  0.55