【问题标题】:How to check user input with csv file and print data from specific column?如何使用 csv 文件检查用户输入并打印特定列的数据?
【发布时间】:2016-08-19 13:46:40
【问题描述】:

我有一个 CSV 文件,其中在不同的列中包含补丁名称、发布日期和一些其他信息。我正在尝试编写一个 Python 脚本,该脚本将询问用户补丁名称,一旦获得输入,将检查补丁是否在 CSV 文件中并打印出发布日期。

到目前为止,我已经根据this的答案编写了以下代码。

import csv

patch = raw_input("Please provide your Patchname: ")

with open("CSV_File1.csv") as my_file1:
    reader = csv.DictReader(my_file1)
    for row in reader:
        for k in row:
            if row[k] == patch:
                print "According to the CSV_File1 database: "+row[k]

这样我可以在屏幕上打印 Patch 名称。我不知道如何使用 Dates 遍历列,以便打印与我作为输入提供的 Patch 名称的行对应的日期。

另外,我想检查一下那个补丁是不是最后一个发布的。如果不是,则打印最新版本及其发布日期。我的问题是 CSV 文件包含不同软件版本的补丁名称,所以我不能只打印列表的最后一个。例如:

PatchXXXYY,...other columns...,Release Date,...     <--- (this is the header row of the CSV file)
Patch10000,...,date
Patch10001,...,date
Patch10002,...,date
Patch10100,...,date
Patch10101,...,date
Patch10102,...,date
Patch10103,...,date
Patch20000,...,date
...

所以,如果我的输入是“Patch10000”,那么我应该得到它的发布日期和最新的可用补丁,在这种情况下是 Patch10002,以及它的发布日期。但不是 Patch20000,因为那将是不同的软件版本。一个更可取的输出是这样的:

根据 CSV_File1 数据库:Patch10100 发布于 “日期”。最新的可用补丁是“Patch10103”,它是 在“日期”发布。

这是因为上面 PatchXXXYY 中的“XXX”数字代表软件版本,“YY”代表补丁编号。我希望这很清楚。

提前致谢!

【问题讨论】:

    标签: python csv input output


    【解决方案1】:

    CSV 模块工作正常,但我只是想将 Pandas 放入其中,因为这可能是一个很好的用例。可能有更好的方法来处理这个问题,但这是一个有趣的例子。这是假设您的列是标签(Patch_Name, Release_Date),因此您需要更正它们。

    import pandas as pd
    
    my_file1 = pd.read_csv("CSV_File1.csv", error_bad_lines=False)
    
    patch = raw_input("Please provide your Patchname: ")
    
    #Find row that matches patch and store the index as idx
    idx = my_file1[my_file1["Patch_Name"] == patch].index.tolist()
    
    #Get the date value from row by index number
    date = my_file1.get_value(idx[0], "Release_Date")
    
    print "According to the CSV_File1 database: {} {}".format(patch, date)
    

    还有很多很好的方法可以用 Pandas 过滤和比较 CSV 中的数据。如果我有更多时间,我会给出更多描述性的解决方案。我强烈建议您查看 Pandas 文档。

    【讨论】:

    • 感谢您的反馈,这是一种有趣的不同方法,我会研究一下!
    【解决方案2】:

    您就快到了,虽然我有点有点困惑 - 您的示例数据没有标题行。如果不是,那么您不应该使用DictReader,但如果是,您可以采用这种方法。

    version = patch[:8]
    latest_patch = ''
    last_patch_data = None
    with open("CSV_File1.csv") as my_file1:
        reader = csv.DictReader(my_file1)
        for row in reader:
            # This works because of ASCII ordering. First,
            # we make sure the package starts with the right
            # version - e.g. Patch200
            if row['Package'].startswith(version):
                # Now we grab the next two numbers, so from
                # Patch20042 we're grabbing '42'
                patch_number = row['Package'][8:10]
                # '02' > '' is true, and '42' > '02' is also True
                if patch_number > latest_patch:
                    # If we have a greater patch number, we
                    # want to store that, along with the row that
                    # had that. We could just store the patch & date
                    # but it's fine to store the whole row
                    latest_patch = patch_number
                    last_patch_data = row
    
            # No need to iterate over the keys, you *know* the
            # column containing the patch. Presumably it's
            # titled 'patch'
            #for k in row:
            #    if row[k] == patch:
            if row['Package'] == patch:
                # assuming the date header is 'date'
                print("According to the CSV_File1 database: {patch!r}"
                      " was released on {date!r}".format(patch=row['Package'],
                                                         date=row['Registration']))
    
        # `None` is a singleton, which means that we can use `is`,
        # rather than `==`. If we didn't even *start* with the same
        # version, there was certainly no patch. You may prefer a
        # different message, of course.
        if last_patch_data is None:
            print('No patch found')
        else:
            print('The latest available patch is {patch!r},'
                  ' which was released on {date!r}'.format(patch=last_patch_data['Package'],
                                                           date=last_patch_data['Registration']))
    

    【讨论】:

    • 我上面给出的示例只是一个示例。但最上面一行是标题。所以我的 CSV 文件如上所示。起初我在“if”语句中遇到语法错误,所以我注意到缺少一个“:”。我将标题的变量名称更改为我的 CSV 文件的相应变量名称(补丁 -> 包和日期 -> 注册)至于最后一个“打印”。补丁是有序的,但正如我所说,有不同的软件版本,所以每次打印最后一个条目不会是正确版本的正确补丁。如果可以,请再次查看我的初始帖子。
    • 哎呀!接得好。我已经修复了语法错误。我没有注意到您的问题中有任何内容指定了一种方法来判断哪个补丁与哪个版本一起使用。或者Patch 之后的第一个整数值是否指定?如果是这样,我可以添加修改。
    • 基本上,我的输入是补丁,然后是一些数字,例如“PatchXXXYY”。我在最后编辑了我的初始帖子,以解释为什么编号很重要。 “所以,如果我的输入是“Patch10000”,那么我应该得到它的发布日期和最新的可用补丁,在这种情况下是 Patch10002,以及它的发布日期。但不是 Patch20000,因为那将是一个不同的软件版本。那是因为上面PatchXXXYY中的“XXX”数字代表软件版本,“YY”代表补丁号,希望清楚。”
    • @italialex7 应该为你做这件事。如果这解决了您的问题,请记住用绿色复选标记将我的答案标记为已接受。如果你觉得它非常有帮助,你也可以点赞。
    • 我想我知道你想要如何检查数字,但是当我运行它时,我仍然会得到列表的最后一个条目作为最新的补丁。因此,以您的代码注释为例,如果我告诉它检查 Patch20002,它应该给我 Patch20042 作为最新的,但我得到的是 Patch23066(这是一个不同的软件版本和补丁)。
    猜你喜欢
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    • 1970-01-01
    相关资源
    最近更新 更多