找到前10名并将其从厘米转换为英寸 - Python

时间:2016-03-26 12:06:36

标签: python python-2.7

我正在从文件中读取数据,如下所示,它是一个.dat文件:

1
Carmella Henderson
24.52
13.5
21.76
2
Christal Piper
14.98
11.01
21.75
3
Erma Park
12.11
13.51
18.18
4
Dorita Griffin
20.05
10.39
21.35

文件本身包含50条记录。根据这些数据,我需要人员编号,姓名和第一个数字,如下所示:

1 #person number
Marlon Holmes  #Name
18.86 # First number
13.02 # Second Number
13.36 # Third Number

我已经有代码来读取数据但是我无法根据#First数字获得前10名结果

前10名中的#First数字目前是厘米,但需要转换为英寸,我不确定如何将前10名和转换合并为数据的读数

读取数据的代码:

 with open('veggies_2016.txt', 'r') as f:
        count = 0
        excess_count = 0
        for line in f:
            if count < 3:
                print(line)
                count += 1
            elif count == 3 and excess_count < 1:
                excess_count += 1
            else:
                count = 0
                excess_count = 0

如上所述,代码读取文件,如#Person number,#name和#first number,但#first number需要转换为英寸,然后需要对所有数据进行排序以找到前10名< / p>

此过程也必须重复#second number和#third number,但它们的代码与#first number

是分开的

我试图读取数据然后附加到列表并对其进行排序并将其转换为但没有成功,任何帮助都将不胜感激

整个代码:

from collections import OrderedDict
from operator import itemgetter
import pprint
def menu():
    exit = False


    while not exit:
        print("To enter new competitior data, type new")
        print("To view the competition score boards, type Scoreboard")
        print("To view the Best Overall Growers Scoreboard, type Podium")
        print("To review this years and previous data, type Data review")
        print("Type quit to exit the program")

        choice = raw_input("Which option would you like?")

        if choice == 'new':
            new_competitor()
        elif choice == 'Scoreboard':
            scoreboard_menu()
        elif choice == 'Podium':
            podium_place()
        elif choice == 'Data review':
            data_review()
        elif choice == 'quit':
            print("Goodbye")
            raise SystemExit

"""Entering new competitor data: record competitor's name and vegtables lengths"""

def competitor_data():
    global competitor_num
    l = []

    print("How many competitors would you like to enter?")

    competitors = raw_input("Number of competitors:")

    num_competitors = int(competitors)

    for i in range(num_competitors):

        name = raw_input("Enter competitor name:")
        Cucumber = raw_input("Enter length of Cucumber:")
        Carrot = raw_input("Enter length of Carrot:")
        Runner_Beans = raw_input("Enter length of Runner Beans:")

        l.append(competitor_num)
        l.append(name)
        l.append(Cucumber)
        l.append(Carrot)
        l.append(Runner_Beans)

        competitor_num += 1

    return (l)
def new_competitor():
    with open('veggies_2016.txt', 'a') as f:
        for item in competitor_data():
            f.write("%s\n" %(item))
def scoreboard_menu():
    exit = False

    print("Which vegetable would you like the scoreboard for?")

    vegetable = raw_input("Please type either Cucumber, Carrot or Runner Beans:")

    if vegetable == "Cucumber":
        Cucumber_Scoreboard()
    elif vegetable == "Carrot":
        Carrot_Scoreboard()
    elif vegetable == "Runner Beans":
        Runner_Beans_Scoreboard()

def Cucumber_Scoreboard():
    exit = True

    print("Which year would you like the Scoreboard from?")

    scoreboard = raw_input("Please type a year:")

    if scoreboard == "2015":
        cucumber_veg_2015()
    elif scoreboard == "2014":
        cucumber_veg_2014()
    elif scoreboard == "2016":
        cucumber_veg_2016()


def cucumber_veg_2016(cm):
    return float(cm) / 2.54

names = OrderedDict([('Competitor Number', int),
                     ('Competitor Name', str),
                     ('Cucumber', cucumber_veg_2016),
                     ('Carrot', float),
                     ('Runner Bean', float)])
data = []
with open('veggies_2016.txt') as fobj:
    while True:
        item = {}
        try:
            for name, func in names.items():
                item[name] = func(next(fobj).strip())
            data.append(item)
        except StopIteration:
            break

pprint.pprint(sorted(data, key=itemgetter('Cucumber'))[:10])

2 个答案:

答案 0 :(得分:1)

解决方案

将数据读入字典列表将起作用:

from collections import OrderedDict
from operator import itemgetter
import pprint

def to_inch(cm):
    return float(cm) / 2.54

names = OrderedDict([('person_number', int),
                     ('name', str),
                     ('first', to_inch),
                     ('second', float),
                     ('third', float)])
data = []
with open('veggies_2016.txt') as fobj:
    while True:
        item = {}
        try:
            for name, func in names.items():
                item[name] = func(next(fobj).strip())
            data.append(item)
        except StopIteration:
            break

pprint.pprint(sorted(data, key=itemgetter('first'))[:10])

输出:

[{'first': 4.76771653543307,
  'name': 'Erma Park',
  'person_number': 3,
  'second': 13.51,
  'third': 18.18},
 {'first': 5.897637795275591,
  'name': 'Christal Piper',
  'person_number': 2,
  'second': 11.01,
  'third': 21.75},
 {'first': 7.893700787401575,
  'name': 'Dorita Griffin',
  'person_number': 4,
  'second': 10.39,
  'third': 21.35},
 {'first': 9.653543307086613,
  'name': 'Carmella Henderson',
  'person_number': 1,
  'second': 13.5,
  'third': 21.76}]

步骤

此辅助函数将厘米转换为英寸:

def to_inch(cm):
    return float(cm) / 2.54

我们使用有序字典来保存我们想要按顺序阅读的不同项目的名称。该值是我们用来转换每个项目的读取值的函数:

names = OrderedDict([('person_number', int),
                     ('name', str),
                     ('first', to_inch),
                     ('second', float),
                     ('third', float)])

我们从一个空列表开始:

data = []

然后打开我们的文件:

with open('veggies_2016.txt') as fobj:

我们做了一些没有定义结束的事情,每次都创建一个新字典item

    while True:
        item = {}

我们尝试从文件中读取,直到它完成,即直到我们得到一个 StopIteration例外:

        try:
            for name, func in names.items():
                item[name] = func(next(fobj).strip())
            data.append(item)
        except StopIteration:
            break

我们浏览订单字典names的键和值并调用每个字典 值,即我们使用func()检索的下一行上的函数next()。 这会将条目转换为所需的数据类型,并为first执行cm-inch转换。阅读完一个人的所有项目后,我们将字典附加到列表data

最后,我们按键first排序并打印出10个条目 (我的示例文件少于10个条目):

pprint.pprint(sorted(data, key=itemgetter('first'))[:10])

与您的代码集成:

您需要将代码放入函数podium_place()

def cucumber_veg_2016(cm):
    return float(cm) / 2.54

def podium_place():
    names = OrderedDict([('Competitor Number', int),
                         ('Competitor Name', str),
                         ('Cucumber', cucumber_veg_2016),
                         ('Carrot', float),
                         ('Runner Bean', float)])
    data = []
    with open('veggies_2016.txt') as fobj:
        while True:
            item = OrderedDict()
            try:
                for name, func in names.items():
                    item[name] = func(next(fobj).strip())
                data.append(item)
            except StopIteration:
                break

    sorted_data = sorted(data, key=itemgetter('Cucumber'), reverse=True)
    for entry in sorted_data[:10]:
        for key, value in entry.items():
            print key, value
        print

menu()

最后,您需要致电menu()。此外,如果top值最大,则需要排序reverse(见上文)。

答案 1 :(得分:0)

我会一次将它们作为记录阅读。您可以将该功能放在使用同一文件多次调用的函数中。当您到达文件末尾时,它可以返回None。它将返回一个元组,其中包含给定记录的所有值(包括转换)。然后,您可以使用sorted使用每条记录中的任何一个值对记录列表进行排序。

def read_record(fid):
    id = fid.readline()

    # At the end of the file
    if id is None:
        return None

    name = fid.readline()

    # Perform the conversion
    number1_inches = float(fid.readline()) / 2.54
    number2 = float(fid.readline())
    number3 = float(fid.readline())

    return (id, name, number1_inches, number2, number3)

with open('filename.txt', 'r') as fid:
    records = list()

    while True
        new_record = read_record(fid)

        # Stop if we hit the end of the file
        if new_record is None:
            break

        records.append(new_record)

    # Now sort the records based on the value of number1
    records = sorted(records, key=lambda x: x[2])