从列表列表

时间:2016-06-21 20:01:00

标签: python python-2.7

这里的CS学生,对如何解决这个问题非常困惑...... mailingLabels.txt只是一个空白文本文件。

以下是customerData.txt的一个示例行:

  

Eric,A,Stutler,568 Nuzum Court,East Aurora,NY,14052,US,Eric.A.Stutler@trashymail.com,716-652-4943,male,11/24/1947

说明:

main函数调用一个新函数generateMailingLabels来处理客户列表以生成一个 仅包含居住在爱荷华州(IA)的女性客户的邮件标签的文本文件。

您应采取的一般方法是:

  • customerList作为参数传递给此函数
  • 打开邮件标签文件(mailingLabels.txt
  • 该函数应循环遍历列表中的所有客户记录
  • 如果记录满足上面列出的标准(来自爱荷华州的女性), 通过连接来自的选择元素来构建邮件标签 客户记录的字段列表和
  • 将邮件标签写入文件(mailingLabels.txt

每个邮寄标签的格式应如下所示,每个标签分隔5个空行:

Jane Smith
123 Main Street
Cedar Falls, IA 50613

这是我目前的代码:

def main():
    """ Opens file, reads customer information into a list, closes the file"""

    custFile = open('customerData.txt','r')
    customerList = generateList(custFile)
    mailingList = open('mailingLabels.txt','w')

    # Echo first and last enter from the customerList
    print "customerList[0]:", customerList[0]
    print "customerList[-1]:",customerList[-1]

    custFile.close()

def generateList(custFile):
    """ Reads customer data from file and returns a list of customers"""
    customers = []
    for line in custFile:
        # Strip the new-line character from the end of the line, then split
        # the line on the commas (',') to get a list of customer fields
        custInfoList = line.strip().split(',')
        customers.append(custInfoList)
    return customers

def generateMailingLabels(customerList):
    """Sorts through the customer list and returns only females living in Iowa."""
    mailingList
    for customer in customerList:
        if customer[5] == 'IA' and customer[10] == 'female':
            mailingList.write(customer)

我意识到这可能是一件容易的事情我只是很难掌握如何正确编码它以便它能够按照我的意愿去做。任何帮助将不胜感激。

编辑:更新代码:

def main():
    """ Opens file, reads customer information into a list, closes the file"""

    with (open('customerData.txt','r') as custFile,
          open('mailingLabels.txt','w') as mailingList):

        customerList = generateList(custFile)
        generateMailingLabels(customerList, mailingList)

        # Echo first and last enter from the customerList
        print "customerList[0]:", customerList[0]
        print "customerList[-1]:",customerList[-1]

def generateList(custFile):
    """ Reads customer data from file and returns a list of customers"""
    customers = []
    for line in custFile:
        # Strip the new-line character from the end of the line, then split
        # the line on the commas (',') to get a list of customer fields
        custInfoList = line.strip().split(',')
        customers.append(custInfoList)
    return customers

def generateMailingLabels(customerList,mailingList):
    """Sorts through the customer list and returns only females living in Iowa."""
    open('mailingLabels.txt','w')

    for customer in customerList:
        if customer[5] == 'IA' and customer[10] == 'female':
            mailingList.write(customer)

    mailingList.close()

main()

3 个答案:

答案 0 :(得分:0)

您在mailingList函数中定义了main(),但generateMailingLabels没有得到它。 (对于其中一个,你好像不是在呼唤它)

如果你添加它,那么你的主要看起来更像:

def main():
""" Opens file, reads customer information into a list, closes the file"""

    custFile = open('customerData.txt','r')
    customerList = generateList(custFile)
    mailingList = open('mailingLabels.txt','w')

    # Echo first and last enter from the customerList
    print "customerList[0]:", customerList[0]
    print "customerList[-1]:",customerList[-1]

    custFile.close()
    generateMailingLabels(customerList, mailingList)

注意generateMailingLabels上的额外参数 - 你也必须将引用传递给函数! generateMailingLabels的足迹现在变为def generateMailingLabels(customerList, mailingList),您可以删除在其第一行中浮动的随机mailingList

编辑:还记得在某处关闭mailingList。因此,学习使用with语句会更好 - 它会自动清理任何可以像文件一样工作的东西(通常只是将它与文件一起使用)

with (open('customerData.txt', 'r') as custFile,
      open('mailingLabels.txt','w') as mailingList):
    customerList = generateList(custFile)
    generateMailingLabels(customerList, mailingList)

然后它会自动关闭。否则就像任何其他块结构一样。

答案 1 :(得分:0)

在开始之前,我想指出,使用Python,您可以让解释器处理文件流的打开和关闭:

with open('customerData.txt','r') as custFile:
    ## do some stuff here that requires the file to be open
    doSomeStuff()

## once outside the loop, Python closes the file for you
doSomeMoreStuff()

关于with open(path, mode) as foo的好处是你不会忘记关闭文件。

对于您的计划,def generateMailingLabels(customerList):

出错

第一个错误是您甚至没有通过main()功能调用它。如果不调用它,函数将如何运行?

接下来我看到的是:

mailingList
for customer in customerList:
    if customer[5] == 'IA' and customer[10] == 'female':
        mailingList.write(customer)

在python中,您无法声明未分配的变量。说mailingList的行除了抛出错误外什么都不做。此外,即使没有实例化,您也会调用mailingList.write()。您需要在该函数中打开文件,或者将打开的mailingList传入其中。我建议在该功能中打开它而不是传入它,但这取决于你。

答案 2 :(得分:0)

您对方法的评论应该是有意义的,并描述该方法的作用。例如,对generateMailingList方法的评论与方法实际执行的操作无关。

此外,在使用Python时,您应该在编写代码时遵循style guide for Python

通过将文件名传递给方法而不是文件处理程序,您可以进一步简化代码 - 同时使其更灵活一些。请记住,一个函数应该只做一件事 - 如果一个函数执行两个/三个不同的操作,则很难调试和隔离问题;更不用说编写好的测试了。

因此,让我们从您的计划需要做的三件事开始:

  1. 阅读源文件
  2. 过滤掉符合条件的记录
  3. 撰写结果
  4. 让我们开始分别编写这些函数:

    def read_records(filename, separator=','):
        "This method reads the source CSV file and returns a list of records"
        results = []
        with open(filename) as f:
           for line in f:
              if line.strip():  # skips blank lines
                  results.append(line.split(','))
    
        return results
    
    def filter_records(records):
        gender = 'female'
        state = 'IA'
        results = []
        for record in records:
           if record[5] == state and record[10] == gender:
               results.append(record)
        return results
    
    def write_results(filename, records):
        "Writes out filtered records, with 5 spaces between each entry"
        with open(filename, 'w') as f:
           for record in records:
               name = '{} {} {}'.format(record[0], record[1], record[2])
               address = '{}\n{}, {} {}'.format(record[3], record[4], record[5], record[6])
               f.write('{}\n{}\n\n\n\n\n'.format(name, address))
    

    接下来,我们需要按正确的顺序调用它们:

    if __name__ == '__main__':
        records = read_records('customerData.txt')
        filtered_records = filter_records(records)
        write_results('mailingLabels.txt', filtered_records)
        print('Done')
    

    代码中有一些地方可以优化,具体取决于您在课堂上讲授的内容。