【问题标题】:Looping over a text file list with python用python循环一个文本文件列表
【发布时间】:2015-11-23 20:47:30
【问题描述】:

编辑:为了更清楚,更新了帖子,还没有答案有帮助!

好的,所以我的任务是获取一个文本文件,每行有 4 个条目,分别是名字、姓氏、小时数和工资率。我要做一些计算并将所有这些信息放入 python 中的格式化表中。现在,我有了将数据输入表格的代码,但它只适用于文本文件中的第一个条目,我不能让它循环。老实说,我觉得自己像个白痴,这只是一个简单的解决方法。

我的输出应该是这样的:

http://i.imgur.com/bIOBqye.png

真的可以使用一些指针来使这个循环通过并打印文本文件每一行的数据。这是我当前代码的外观:

heading1 = "{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name",         "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay")
heading2=    "=============================================================================================================="

print(heading1)
print(heading2)

if os.path.isfile(fileQuestion) == True:
file = open('emps', 'r')
data = file.readlines()
for tmp in data:

    data2= [word.rstrip("\n") for word in data]
    first = data2[0].split()

    lastName = first[0]
    firstName = first[1]
    first[2]=(int(first[2]))
    first[3]=(int(first[3]))
    initialHours = first[2]
    payRate = first[3]

    if initialHours > 40:
        overHours = initialHours - 40
        regHours = 40
        regPay = payRate * regHours
        otPay = overHours * (payRate * 1.5)
        grossPay = regPay + otPay

    else:
        regHours = first[2]
        grossPay = initialHours * payRate
        overHours = 0



    heading3= "{0:15s}{1:15s}{2:2d}{3:10d}{4:14d}   {5:24.2f}".format(firstName, lastName, regHours, payRate, overHours, grossPay)
    heading4= "{0:15s}{1:21.2f}".format("Total Gross Pay", grossPay)
    heading5= "{0:15s}{1:19.2f}".format("Average Gross Pay", grossPay)
    heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", 33)
    spaceHeading = "               "

    print(heading3)
    print(spaceHeading)
print(heading4)
print(heading5)
print(heading6)

如果我没有正确完成此操作或其他任何事情,请告诉我,这是第一次。谢谢。

【问题讨论】:

  • file.readlines() 读取所有行并放入一个字符串。您应该在循环中使用 f.readline 。查找正确的语法

标签: python


【解决方案1】:

我发现了重复,并认为有些人对待粗鲁;/ 只是不关注程序员的实用问题,而是以糟糕的方式关注 Stack 的良好规则:(

这是我对您问题的完整答案:

1) 首先,您必须记住,ident 是针对其他语言已知的代码块括号使用的。

我重新格式化了您的代码,请记住,当您将其粘贴到此处时,所有行的开头都应该有额外的空格;)

2) 就像有人说的那样:

first = word.split()

修复“不改变”循环中的行。

3) 总加班时间有硬编码:

heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", overHours)

此外,overHours(All?) 不应在循环中的“else”块中“归零”。您必须在循环之前对其进行初始化。

我更改了其他一些地方,即一些硬编码的整数,也许它不理想并且不符合您的风格,但是您的代码在下面有我的修复...

最好,如果您使用 GitHub 或 Bitbucket 或其他可通过网络访问的存储库,因为如果您愿意,您可以帮助做出贡献,并且您自己也可以找到所做的所有更改。然后,请在这里帮助解决极其未知的问题。在学习的乞求中总是很难发现,但后来 - 你可以取得更多成就!

这是我更改后的代码:

from os.path import isfile as isFileExsist
import sys

filePath = input("What is the name of your file?: ")

while isFileExsist(filePath) == False:
    pos = ['y', 'Y', 'yes', 'Yes']
    neg = ['n', 'N', 'no', 'No']
    answer = input("File not found! Do you want to start again? (y-yes/n-no)")
    if answer in neg:
        exit("Bye!")
    elif answer in pos:
        filePath = input("What is the name of your file?: ")
        continue
    else:
        print("Not sure what is the answer. Try again!")
        continue

file = open(filePath, 'r')
data = file.readlines()

print("{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name",   "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay"))
print("==============================================================================================================")

overHoursAll = 0
grossPayAll = 0
count = 0

for line in data:
    words = line.split()

    lastName = words[0]
    firstName = words[1]
    initialHours=(int(words[2]))
    payRate =(int(words[3]))

    if initialHours > 40:
        regHours = 40
        overHours = initialHours - 40

        regPay = payRate * regHours
        otPay = overHours * (payRate * 1.5)
        grossPay = regPay + otPay
    else:
        regHours = initialHours
        overHours = 0

        grossPay = initialHours * payRate


    grossPayAll += grossPay
    overHoursAll += overHours

    # heading3
    print("{0:15s}{1:15s}{2:2d}{3:10d}{4:14d}{5:24.2f}".format(firstName, lastName, regHours, payRate, overHours, grossPay))
    # space heading
    print("               ")

# overall stats
print("{0:15s}{1:21.2f}".format("Total Gross Pay", grossPayAll))
print("{0:15s}{1:19.2f}".format("Average Gross Pay", grossPayAll / len(data)))
print("{0:15s}{1:16d}".format("Total Overtime Hours", overHoursAll))

最好的问候,对不起我的英语。

【讨论】:

    【解决方案2】:

    好吧,我认为,您可能想要data2 = [word.rstrip("\n") for word in tmp],但如果没有看到示例输入和所需输出,就很难判断。

    还有,

    first[2]=(int(first[2]))
    first[3]=(int(first[3]))
    initialHours = first[2]
    payRate = first[3]
    

    可能是:

    initialHours = int(first[2])
    payRate = int(first[3])
    

    但您还需要更改对 first[2] 的其他引用

    最后,我会改变

    if os.path.isfile(fileQuestion) == True:
    file = open('emps', 'r')
    data = file.readlines()
    for tmp in data:
    

    到:

    if os.path.isfile(fileQuestion) == True:
    with open('emps', 'r') as myfile:
        for tmp in myfile:
    

    这确保文件被正确关闭(您的代码不会关闭它),并直接遍历文件,而不是使用readlines(),后者在执行其他操作之前不必要地将整个文件读入内存。请注意,file 是一个 python builtin,所以变量名的选择不好。

    【讨论】:

    • 嗨,我已经更新了我想要的输出,如果可以的话。实现您的代码后,我仍然遇到问题。 :\谢谢!
    【解决方案3】:

    您正在使用这些行:

    data = file.readlines()
    for tmp in data:
    

    它已经将您的数据分成几行,并遍历它们。这意味着这一行 [data2= [word.rstrip("\n") for word in data]] 将 data2 设置为每次的第一行,这使得原始 for 循环无用。

    试试吧:

    tmp = tmp.split()
    

    这将在您迭代时拆分每一行,您现在可以将 tmp 作为列表调用,就像您调用 first 一样,除了它将反映每一行的值。

    您也可以将原来的 for 循环更改为:

    for tmp in file:
    

    因为 python 中的文件对象是产生每一行的生成器(这可以节省一些内存空间)

    【讨论】:

      【解决方案4】:

      尝试这些更改:

      totothrs = 0
      totgross = 0.0
      employees = 0
      for tmp in data:
          employees += 1
          fname, lname, rate, hrs = tm.split()
          hrs = int(hrs)
          rate = float(rate)
          othrs = 0
          if hrs > 40:
              othrs = hrs - 40
              hrs = hrs - othrs
      
          totothrs += othrs
          gross = rate * hrs + (1.5*rate)*othrs
          totgross += gross
          heading3= "{0:15s}{1:15s}{2:2d}{3:10d}{4:14d}   {5:24.2f}".format(firstName, lastName, hrs, rate, othrs, gross)
          print heading3
      
      spaceHeading = "       "
      heading4= "{0:15s}{1:21.2f}".format("Total Gross Pay", totgross)
      heading5= "{0:15s}{1:19.2f}".format("Average Gross Pay", (totgross/employees)
      heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", totothrs)
      
      print heading4
      print heading5
      print heading6
      

      注意:您不需要定义“headingN”,只需打印它们即可

      【讨论】:

        【解决方案5】:
        import os.path
        import sys
        #fileQuestion = input("What is the name of your file?: ")
        fileQuestion = "Testfile.txt"
        heading1 = "{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name",   "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay")
        heading2=    "=============================================================================================================="
        
        print(heading1)
        print(heading2)
        
        if os.path.isfile(fileQuestion) == True:
            file_handle = open(fileQuestion, 'r')
        #file = open('emps', 'r')
        #data = file.readlines()    I would't go for readline here
        
        #file_handle2 = open('outupt.txt')
        total_gross_pay = 0
        number_of_employees = 0
        average_gross_pay = 0
        total_overtime = 0
        standard_working_hours = 40
        
        for i in file_handle:
            data = i.rstrip().lstrip().split()
        
            #print (data)
            first_name, last_name, hours, payrate = data
        
            hours = int(hours)
            payrate = int(payrate)
            basic_pay = hours * payrate
        
            if(hours > standard_working_hours):
                overtime = hours - standard_working_hours
                overtime_premium = overtime * payrate
                gross_pay = overtime_premium + basic_pay
        
            else:
                overtime = 0
                gross_pay = basic_pay
        
            total_overtime += overtime
            total_gross_pay += gross_pay
            number_of_employees += 1
        
            print("{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format(first_name, last_name, str(hours), str(payrate), str(overtime), str(gross_pay)))
        
        print('\n')
        print("Total Gross Pay:   ",total_gross_pay)
        print("Average Gross Pay: ",total_gross_pay/number_of_employees)
        print("Total overtime:    ",total_overtime)
        

        【讨论】:

        • 以上代码适用于您描述的文本文件的输入格式,希望对您有用。
        猜你喜欢
        • 1970-01-01
        • 2017-06-17
        • 2020-05-30
        • 2014-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多