【问题标题】:tuples and lists元组和列表
【发布时间】:2012-12-06 19:48:18
【问题描述】:

我有一个由 Python 中的元组组成的列表。我需要引用每个元组的每个索引来创建 NBA 球员统计数据列表。元组中的第一个索引 [0] 是效率等级,接下来的两个位置是球员姓名,最后是球队名称。现在元组在一个很长的列表中。当我运行程序时,我得到的只是前四个元组的输出,而不是各种元组的列表。我曾尝试使用 append,但这也无济于事。

这是我的代码:

def get_data_list (file_name):
    data_file = open(file_name, "r")
    data = []
    player_list=[]
    for line_str in data_file:

        # strip end-of-line, split on commas, and append items to list
        data_list =line_str.strip().split(',')

        data_list.append (data)

        gp=int(data_list[6])
        mins=int(data_list[7])
        pts=int(data_list[8])
        oreb=int(data_list[9])
        dreb=int(data_list[10])
        reb=int(data_list[11])
        asts=int(data_list[12])
        stl=int(data_list[13])
        blk=int(data_list[14])
        to=int(data_list[15])
        pf=int(data_list[16])
        fga=int(data_list[17])
        fgm=int(data_list[18])
        fta=int(data_list[19])
        ftm=int(data_list[20])
        tpa=int(data_list[21])
        tpm=int(data_list[22])



        efficiency = ((pts+reb+asts+stl+blk)-(fgm-ftm-to))/gp        

       data_list.append (efficiency)
       data.append(data_list)
       score=data_list[24]
       first_name=data_list[2]
       last_name=data_list[3]
       team_name=data_list[4]
       player_tuple = score, last_name, first_name, team_name

       player_list.append(player_tuple)

       a=sorted(player_list)

       a.reverse()

   return a

def print_results (lst):
   """Print the result in a nice format"""
    print("The top 50 players based on efficiency are: ")
    print('*'*75)
    print('{:<20s}{:<20s}, {:<15s}{:<5s}'.format(lst[(0)],lst[(1)],lst[(2)],lst[(3)]))

file_name1 = input("File name: ")

result_list = get_data_list (file_name1)

top_50_list=[]
top_50_list=result_list[:50]

print_results(top_50_list)

我认为我的问题出在 print_results 函数中。

请记住,我正在参加入门课程,因此许多高级选项不适合我。请保持解决方案简单。

玻利弗

【问题讨论】:

  • 你应该循环访问print_results中的yoru玩家吗?它只显示您列表中的 4 个索引
  • "data_list.append (efficiency)" 到 "a.reverse()" 行的缩进有点偏离。请记住,Python 对缩进很敏感。这只是您粘贴代码时的错误吗?

标签: python python-3.x tuples


【解决方案1】:

看来你的问题出在 append 函数上……

a=[some,list]
a.append(42) #a = [some,list,42]
a.append([1,2]) #now a = [some,list,42,[1,2]]

对你来说,索引 0 本身就是一个空列表

所以在你的代码中,对于循环的第一次迭代:

data_list =line_str.strip().split(',')  # data_list = [some,list]
data_list.append (data)                 # data_list = [some,list,[]]  
...
data_list.append (efficiency)           # data_list = [some,list,[],efficiency]
data.append(data_list)                  # data = [[some,list,[],efficiency]]
...
a = something special

然后循环继续直到输入文件的最后一行

然后你返回aa 只返回一次,并且由于前面提到的洗牌而变得混乱。

玩一下 for 循环并追加一点,你应该没问题。

如果您感到勇敢,请查看yield。发电机在这里是完美的

【讨论】:

    【解决方案2】:

    print_results

    def print_results (lst):
       """Print the result in a nice format"""
        print("The top 50 players based on efficiency are: ")
        print('*'*75)
        print('{:<20s}{:<20s}, {:<15s}{:<5s}'.format(lst[(0)],lst[(1)],lst[(2)],lst[(3)]))
    

    可能是这样的

    def print_results(lst):
      """Print the result in a nice format"""
      print("The top 50 players based on efficiency are: ")
      print('*'*75)
      for player_tuple in lst:
         print('{:<20s}{:<20s}, {:<15s}{:<5s}'.format(*player_tuple[:4]))
    

    因为你有一个元组列表,每个元组代表一个玩家,循环遍历每个玩家并打印出他们的信息

    【讨论】:

    • 这让它打印了多行,只是它一遍又一遍地打印同一行。它获取第一个元组并在其整个索引 [0] 中生成它,然后是第二个元组索引 [1] 等等。
    • 我现在明白了。我有一个错字,它不起作用。现在我只需要清理输出。感谢所有的帮助。
    【解决方案3】:

    我不明白你的代码试图用datadata_list 做什么。我重写了它以摆脱data。此外,在计算 efficiency 之后,您将其附加到列表中,但随后您似乎又将其从列表中拉出为 score。我只是摆脱了它。

    对于处理文件,最佳做法是使用 with 语句,所以我重写了这样做。

    此外,您一次将字符串项转换为整数,而您可以通过列表理解一次完成所有操作。我希望列表推导对您来说不是问题,因为它们使代码更清晰。第一个列表解析在三个名称字符串中的每一个上调用.strip() 方法函数。第二个以一种方便的方式转换所有整数。

    我没有创建一个名为a 的临时列表然后反转该列表,而是在sorted() 中指定了reverse=True 选项。现在列表以相反的顺序构建,正是您想要的。

    正如其他人所指出的,您的打印函数需要一个循环来打印列表中的内容。由于打印函数中的消息说它打印前 50 个,我将列表切片更改为在打印函数内部进行。现在 print 函数接受一个可选参数,指定要打印的项目数;它有一个默认值 50,所以如果你不指定另一个值,它会打印前 50 个项目。

    虽然您不需要这样做,但 Python 的一个常见功能是将 if __name__ == __main__: 放在您的代码之前。可以看这里的解释:What does if __name__ == "__main__": do?

    def get_data_list (file_name):
        player_list=[]
        with open(file_name, "r") as f:
            for line in f:
                # split line on commas, and convert items to integer values
                # make a list of the integer values.
                items = line.split(',')
    
                first_name = items[2].strip()
                last_name = items[3].strip()
                team_name = items[4].strip()
    
                data_list = [int(x) for x in items[6:]
                gp = data_list[0]
                mins = data_list[1]
                pts = data_list[2]
                oreb = data_list[3]
                dreb = data_list[4]
                reb = data_list[5]
                asts = data_list[6]
                stl = data_list[7]
                blk = data_list[8]
                to = data_list[9]
                pf = data_list[10]
                fga = data_list[11]
                fgm = data_list[12]
                fta = data_list[13]
                ftm = data_list[14]
                tpa = data_list[15]
                tpm = data_list[16]
    
                efficiency = ((pts+reb+asts+stl+blk)-(fgm-ftm-to))/gp        
    
                player_tuple = efficiency, last_name, first_name, team_name
    
                player_list.append(player_tuple)
    
        return sorted(player_list, reverse=True)
    
    def print_results(lst, how_many=50):
        """Print the result in a nice format"""
        template = '{:<20}{:<20s}, {:<15s}{:<5s}'
    
        print("The top {} players based on efficiency are: ".format(how_many))
        print('*'*75)
        for tup in lst[:how_many]:
            print(template.format(tup[0], tup[1], tup[2], tup[3]))
    
    if __name__ == "__main__":
        file_name1 = input("File name: ")
        result_list = get_data_list(file_name1)
        print_results(result_list)
    

    现在我要进一步平滑它。这是在 Python 中使用了更高级的特性,但它们是使事情变得更方便的特性,而不是只是棘手的事情。

    首先,我们将使用生成器表达式并将项目直接解包为变量名,而不是使用列表推导式构建列表,然后按索引号选择项目。生成器表达式就像一个列表推导式,只是它不是构建一个列表,而是提供一个可以循环的“迭代器”,或者可以解压缩为变量名,就像我在这里展示的那样。

    其次,在打印函数中,我们只想按顺序打印元组中的所有值。 Python 提供了一个快捷方式:在对 .format() 的调用中的元组前面放置一个 * 意味着“解包并使用解包后的值作为此函数调用的参数”。

    def get_data_list (file_name):
        player_list=[]
        with open(file_name, "r") as f:
            for line in f:
                # Split line on commas and convert each item to integer.  Unpack
                # values directly into variable names.  We are using a
                # generator expression to convert all the items to integer,
                # and Python's ability to unpack an iterator into a tuple.
                items = line.strip().split(',')
    
                # use list slicing to select just the three string values
                first_name, last_name, team_name = (s.strip() for s in items[2:5])
    
                # Use a generator expression to convert all values to int.
                # Unpack directly to variable names using tuple unpacking.
                # Put parentheses so Python won't worry about multiple lines
                # of variable names.
                (
                    gp, mins, pts, oreb, dreb, reb, asts,
                    stl, blk, to, pf, fga, fgm, fta, ftm,
                    tpa, tpm
                ) = (int(x) for x in items[6:])
    
                efficiency = ((pts+reb+asts+stl+blk)-(fgm-ftm-to))/gp        
    
                player_tuple = efficiency, last_name, first_name, team_name
    
                player_list.append(player_tuple)
    
        return sorted(player_list, reverse=True)
    
    def print_results(lst, how_many=50):
        """Print the result in a nice format"""
        template = "{:<20}{:<20s}, {:<15s}{:<5s}"
    
        print("The top {} players based on efficiency are: ".format(how_many))
        print('*'*75)
        for player_tuple in lst[:how_many]:
            print(template.format(*player_tuple))
    
    if __name__ == "__main__":
        file_name1 = input("File name: ")
        result_list = get_data_list(file_name1)
        print_results(result_list)
    

    编辑:这是另一个经过编辑的版本。这个将解析一行的逻辑分解为player_tuple 到它自己的函数中。这使得get_data_list() 非常短。

    def player_tuple(line):
        # Split line on commas and convert each item to integer.  Unpack
        # values directly into variable names.  We are using a
        # generator expression to convert all the items to integer,
        # and Python's ability to unpack an iterator into a tuple.
        items = line.strip().split(',')
    
        # use list slicing to select just the three string values
        first_name, last_name, team_name = (s.strip() for s in items[2:5])
    
        # use a generator expression to convert all values to int
        # unpack directly to variable names using tuple unpacking
        (
            gp, mins, pts, oreb, dreb, reb, asts,
            stl, blk, to, pf, fga, fgm, fta, ftm,
            tpa, tpm
        ) = (int(x) for x in items[6:])
    
        efficiency = ((pts+reb+asts+stl+blk)-(fgm-ftm-to))/gp        
    
        return efficiency, last_name, first_name, team_name
    
    def get_data_list(file_name):
        with open(file_name, "r") as f:
            player_list = [player_tuple(line) for line in f]
        return sorted(player_list, reverse=True)
    
    def print_results(lst, how_many=50):
        """Print the result in a nice format"""
        template = "{:<20}{:<20s}, {:<15s}{:<5s}"
    
        print("The top {} players based on efficiency are: ".format(how_many))
        print('*'*75)
        for player_tuple in lst[:how_many]:
            print(template.format(*player_tuple))
    
    if __name__ == "__main__":
        file_name1 = input("File name: ")
        result_list = get_data_list(file_name1)
        print_results(result_list)
    

    现在我们将player_tuple() 作为一个函数,我们可以进一步简化get_data_list()。我不会重复整个程序,只是简化的get_data_list()。如果我必须解决这个问题,这可能是我要编写的代码。

    def get_data_list(file_name):
        with open(file_name, "r") as f:
            return sorted((player_tuple(line) for line in f), reverse=True)
    

    这里我们甚至没有明确地构建列表。我们只需要创建一个生成器表达式来提供所有player_tuple 值,然后直接将其传递给sorted()。无需在get_data_list() 中为该列表命名;它可以在一行中构建和返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-19
      • 1970-01-01
      • 2019-03-22
      • 2017-12-06
      • 2012-10-31
      • 1970-01-01
      相关资源
      最近更新 更多