【问题标题】:Issue with "if" statement in PythonPython中的“if”语句问题
【发布时间】:2013-05-23 12:25:56
【问题描述】:

我有一个文件,我正在尝试使用 Python 中的数据填充第二个文件。在填充时,我正在应用一些 if 语句来操作第二个文件中的一列。

我想使用这些 if 语句执行的操作:检查文件中的第 31 列,如果其值为 0,则在第 32 列返回 0 值,如果其值为空白,则返回 2 值第 32 列和其他所有非零和非空白值在第 32 列返回 1 值。

with open('DE_Combined_' + time.strftime("%Y-%m-%d")+".csv", "rb") as in_file, open('DE_Combined_PD_' + time.strftime("%Y-%m-%d")+".csv", "wb") as out_file:
   reader = csv.reader(in_file)
   writer = csv.writer(out_file)
   headers = next(reader, None)  # returns the headers or `None` if the input is empty
   if headers:
        writer.writerow(headers)
   for row in reader:
       if row[30] != 0:
           row[31] = 1
       else:
           row[31] = 0
       if row[30] == "":
           row[31] = 2
       writer.writerow(row)

这似乎是一个非常简单的问题,但我的输出文件给了我错误的结果。它在第 32 列中具有 1 值,在第 31 列中具有 0 值。两列中都应该是0。尽管2 值与第 31 列中的blank 值相对。

请帮助我解决这个问题,因为在我多次尝试发现我使用的 if 语句的逻辑有问题之后,我现在一无所知。

实际 O/P 的片段:(两行中的最后 2 个条目是相关的列)

05/23/2013  May 2013    2013    4   2   Thursday    UK  O2  £   NOKIA   100 NOKIA 100   Smartphone  Symbian NA          9.99            N       Pay & Go    Pay & Go                    0.64222 0   1
05/23/2013  May 2013    2013    4   2   Thursday    UK  O2  £   NOKIA   100 NOKIA 100   Smartphone  Symbian NA  Pink        9.99            N       Pay & Go    Pay & Go                    0.64222 0   1

I/P Snippet:(前 2 行)(最后 2 列是相关列)

Date,Month,Fiscal_Year,Calendar_Year,FY_Quarter,CY_Quarter,Day_of_Week,Geography,MO,Currency,Device_OEM,Device_Name,GDN,Device_Type,Device_OS,Device_Franchise,Device_Color,Device_Storage_in_GB,Device_Price,Device_Monthly_Price,Additional,Device_Refurb,Plan_COMPARISON,Plan_Name,Plan_Contract_Length,Plan_Monthly_Price,Plan_Data_in_GB,Plan_Minutes,Plan_Texts,Exchange_Rate_vs_1USD,Difference,Difference_Flag
05/23/2013,May,2013,2013,4,2,Thursday,UK,O2,£,NOKIA,100,NOKIA 100,Smartphone,Symbian,NA,,,9.99,,,N,,Pay & Go,Pay & Go,,,,,0.64222,0.0,
05/23/2013,May,2013,2013,4,2,Thursday,UK,O2,£,NOKIA,100,NOKIA 100,Smartphone,Symbian,NA,Pink,,9.99,,,N,,Pay & Go,Pay & Go,,,,,0.64222,0.0,

【问题讨论】:

  • 在 for 循环之后添加一个 print row,它看起来像您期望的那样吗?或使用实际输入更新您的问题。现在我们只能猜测......
  • 您是否考虑过拆分读写功能?首先读取输入 csv,使用要写入的数据填充列表,根据需要进行操作,然后写入输出文件。我在想row[30] != 0 row[31] = 1之间发生了什么事
  • @multiphrenic 你能帮我设计那种方法吗?我对编程很陌生
  • O/P 部分包含 28 和 29 列。那部分是输入还是输出?我们需要输入才能帮助您...
  • 它看起来像 28 或 29,因为行中存在空列。

标签: python if-statement python-2.7 for-loop with-statement


【解决方案1】:

来自docs

从 csv 文件中读取的每一行都作为字符串列表返回。不执行自动数据类型转换。

也许你的if row[30] != 0 应该改为if row[30] != "0"

【讨论】:

  • 此方法部分有效,我的大约一半的行仍然显示 1 而不是 0 值。
【解决方案2】:

如果我把你的逻辑改成这样(记住,除非你使用int()float() 等对它们进行转换,否则一切都是字符串)

for row in reader:
    print "'%s'" % row[30]
    if float(row[30]) != 0:
        row[31] = '1'
    else:
        row[31] = '0'
    if row[30] == "":
        row[31] = 2
    writer.writerow(row)

我得到这个输出:

05/23/2013,May,2013,2013,4,2,Thursday,UK,O2,£,NOKIA,100,NOKIA 100,Smartphone,Symbian,NA,,,9.99,,,N,,Pay & Go,Pay & Go,,,,,0.64222,0.0,0
05/23/2013,May,2013,2013,4,2,Thursday,UK,O2,£,NOKIA,100,NOKIA 100,Smartphone,Symbian,NA,Pink,,9.99,,,N,,Pay & Go,Pay & Go,,,,,0.64222,0.0,0

其中最后一个元素为 0;这就是问题所在,对吧?

【讨论】:

  • 我想要的是最后一列中的 0 值,如果值是非零且非空白,则最后一列中的值为 0.0 或 0,最后一列中的值为 1。对于空白,我希望在最后一列中有 2 个
  • 问题已解决,我将其转换为浮动。从您的评论中得到提示。我使用了float(row[30]) != 0,它适用于整个文件
  • 您能否使用此行float(row[30]) != 0 更改您的答案,因为它会更好地帮助其他用户。
【解决方案3】:

将您的任务分成读取、操作和写入数据的函数。

要将表格读入列表:

def importCSV(fname):
    """ Returns a tuple using a CSV as input. First tuple is the
    header. 
    Second tuple is a dictionary with all the data.
    """
    data = []
    with open(fname, 'rb') as csvfile:
        reader = csv.DictReader(csvfile, delimiter=',')
        header = reader.fieldnames
        for lines in reader:
            data.append(lines)
        return (header, data)

header, data = importCSV('myfile.csv')

现在操作您的数据:

for line in data:
    do something to line...
....

然后写你的数据:

def CreateCSVFromList(header, source, outputfile):
    """Creates a CSV from a 2D List.
    Header should be a simple list for each column in the resulting list.
    Source is the list.
    Output file is what is written. Include the .csv extension please.
    No error-checking is being done at the moment.
    """
    import csv
    with open(outputfile, 'wb') as csvfile:
        writer = csv.writer(csvfile, dialect='excel')
        writer.writerow(header)
        for row in source:
            writer.writerow(row)


CreateCSVFromList(header, data, 'output.csv')

【讨论】:

  • 我尝试使用这个和这个部分来填充最后一列` row[31] = 1 if row[30] == "0.0": row[31] = 0 if row[30] = = "0": row[31] = 0 if row[30] == "": row[31] = 2` ` 它给了我这个错误` if row[30] == "0.0": KeyError: 30 `
  • 我不明白你在做什么。您是否使用importCSV() 创建了标题和数据?您是否为该函数的结果命名,例如标题、数据?如果是这样,您将有一个名为data 的列表。然后,您可以根据需要修改该列表中的项目。如果您想验证该列表中的第 30 项并将第 31 项替换为 1,您可以这样做:if data[29] == "0.0": data[30] = 1
  • 事实证明,我应该在比较数字时使用 float() 和 int()。 float() 解决了我的问题,但感谢您的回答,因为我现在知道执行此任务的新方法。
【解决方案4】:

试试这个:

_buffer = ''
for row in reader:
    if reader.line_num == 31:
        if row == ['']:             #check whether 31st row is empty
            _buffer = 2               #if that's true write `2`to line 32

        elif row == ['0']:      #if that's false check wheter 31st row = 0
            _buffer = 1           #if true, write `1`to line 32

        else:                 
            _buffer = 1 

    if reader.line_num == 32:
        row = _buffer

    writer.writerow(row)

【讨论】:

  • 不,没用。 csv文件处理会不会有问题?
  • 我猜问题出在forloop。您不必为了检查一行就缩放整个文件!尝试类似if reader[30]=="" ...
  • 我正在以wb 模式逐行填充第二个文件。如何在 for 循环之外执行此检查和更改?
  • @atams - 请用您的实际输入中的一些行更新您的问题;没有它,我们只能猜测!
  • 那是因为您没有使用与 OP 相同的输入,显然数据格式为“0.0”。 OP 并没有描述这一点......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-31
  • 1970-01-01
  • 2012-11-19
相关资源
最近更新 更多