【问题标题】:How to execute the "if statement" inside a for loop before "print statement"如何在“打印语句”之前在for循环中执行“if语句”
【发布时间】:2021-12-24 14:57:17
【问题描述】:

我对 Python 中的文件处理和 csv 文件相当陌生。

代码

import csv
file1=open("Employee.csv","w",newline='\r\n')
empwriter=csv.writer(file1)
empwriter.writerow(["EmpID.","Name","MobNo."])
n=int(input("How many employee records do you want to add?:"))
for i in range(n):
    print("\nEmployee Record",(i+1))
    empid=input("Enter empID:")
    name=input("Enter Name:")
    mob=input("Enter Mobile No.:")
    emprec=[empid,name,mob]
    empwriter.writerow(emprec)
file1.close()

file2=open("Employee.csv","r+",newline='\r\n')
empreader=csv.reader(file2)
newwriter=csv.writer(file2)
check=input("\nEnter the empID to check:\n")
opt=int(input('''Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3Update the whole record\n\n'''))

if opt==1:
    for x in empreader:
        if x[0]==check:
            newname=input("Enter new name:")
            x[1]=newname
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)
elif opt==2:
    for x in empreader:
        if x[0]==check:
            newmob=input("Enter new Mobile No.:")
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)     
elif opt==3:
    for x in empreader:
        if x[0]==check:
            newname=input("Enter new name:")
            newmob=input("Enter new Mobile No.:")
            x[1]=newname
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)
file2.close()

我曾在这段代码中尝试过

  1. 按用户输入记录(empID、Name、MobNo.)并制作一个 csv 文件。
  2. 使用 empID 查找所需记录。
  3. 更新该记录。
  4. 显示所有记录。

当我执行代码时,for 循环中的 print 语句在 if 语句之前执行并给我这个输出。

输出

How many employee records do you want to add?:3

Employee Record 1
Enter empID:001
Enter Name:John
Enter Mobile No.:1234567890

Employee Record 2
Enter empID:002
Enter Name:Jane
Enter Mobile No.:2345678901

Employee Record 3
Enter empID:003
Enter Name:Judy
Enter Mobile No.:4567890123

Enter the empID to check:
002
Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record

2
['EmpID.', 'Name', 'MobNo.']
['001', 'John', '1234567890']
Enter new Mobile No.:1111222233
Record Updated Successfully!
 Updated record:
 ['002', 'Jane', '1111222233']
['002', 'Jane', '1111222233']

正如您在输出的最后几行中看到的那样。打印语句在 if 语句(或类似语句)之前执行。我实际上希望输出以下面给定的方式显示...

期望的输出

2
Enter new Mobile No.:1111222233
Record Updated Successfully!
 Updated record:
 ['002', 'Jane', '1111222233']
['EmpID.', 'Name', 'MobNo.']
['001', 'John', '1234567890']
['002', 'Jane', '1111222233']
['003', 'Judy', '4567890123']

【问题讨论】:

  • 您需要使用另一个for 循环来打印整个文件,或者将其存储在某个数组中。
  • 当我在 empreader 中添加 ``` for rec 时:print(rec) `` 在最后.. 没有任何变化.. 如果可能的话,你可以分享一个简单版本的你想说的话?

标签: python csv for-loop if-statement


【解决方案1】:

我可以看到正在发生的事情,以及为什么它不是您所期望的。

看看这个块:

elif opt==2:
    for x in empreader:
        if x[0]==check:
            newmob=input("Enter new Mobile No.:")
            x[2]=newmob
            print("Record Updated Successfully!\n Updated record:\n",x)
            newwriter.writerow(x)
        print(x)  

实际情况是,对于x 中的每一行empreader

  1. ID col x[0] 正在根据您输入的 ID check 进行评估。 如果匹配:
    1. 你中断循环,并介入修改x
    2. 写出新值newwriter.writerow(x)
    3. 然后你走出去......
  2. 打印您的更新,print(x)

除非x[0]==checkFalse,在这种情况下x 只是被打印出来。

考虑(并测试)当您为 check 提供不存在的 ID 时会发生什么...它永远不会进入您的“修改界面”,而只会打印 @987654334 中的每个(未修改的)行@。

然后会发生什么,您是否显示错误消息让用户知道他们选择了错误的 ID?

这是一个相当大的变化,但我认为它使逻辑和您的意图更加清晰......您不是在循环中做出决定,这非常困难。以“平坦”的顺序接受输入并做出决定:

import csv
import sys

# Get the employee ID
check=input("\nEnter the empID to check:\n")

# and check the ID in the employee records
emp_row = None
with open("Employee.csv","r",newline='\r\n') as f:
    empreader=csv.reader(f)

    for x in empreader:
        if x[0] == check:  # the employee ID matches
            emp_row = x[:]

if emp_row is None:
    print(f'Could not find employee ID {check}')
    sys.exit(0)  # or exit(1) to show it's an "error"

# Now you know you have a valid ID, because emp_row has data

opt=int(input('''Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record\n\n'''))

if opt == 1:
    newname = input("Enter new name:")
    emp_row[1] = newname
# else if opt == 2:
#    ...
# else if opt ==3:
#    ...

# Now how do you overwrite the old row in Employee.csv with emp_row?
# Don't try to "modify" the original file as you're reading it, instead...
# Read from the old file, copying all the old rows, except for emp_row, to a new list

new_rows = []
with open('Employee.csv', 'r', newline='\r\n') as f_in:
    reader = csv.reader(f_in)
    header_row = next(reader)
    new_rows.append(header_row)

    for row in reader:
        if row[0] == check:
            new_rows.append(emp_row)
        else:
            new_rows.append(row)

# Then write your new_rows out
with open('Employee.csv', 'w', newline='\r\n') as f_out:
    writer = csv.writer(f_out)
    writer.writerows(new_rows)

我从 Employee.csv 开始,看起来像这样:

EmpID.,Name,MobNo.
001,John,1234567890
002,Jane,2345678901
003,Judy,4567890123

我运行了它,它看起来像这样:

% python3 main.py

Enter the empID to check:
002
Which of the following fields do you want to update?:
1.Update the Name
2.Update the Mobile No.
3.Update the whole record

1
Enter new name:Alice

Employee.csv 现在看起来像:

EmpID.,Name,MobNo.

001,John,1234567890

002,Alice,2345678901

003,Judy,4567890123

(我在 Mac 上,所以 \r\n 添加行)

【讨论】:

  • 没有错误发生并且代码自行执行(它不应该因为 ID 不存在而执行)。是的,正如你所说,它在 empreader 中打印了每一行未修改的行。谢谢你解释我哪里出错了,但你能建议我下一步做什么吗?
  • 刚刚更新了答案,这是一个很大的变化,但我认为随着您的发展和成为更好的程序员,这对您有好处:)
  • 非常感谢您抽出时间并实际帮助我。文件处理对我来说是一个相当新的话题,也许正因为如此,我在理解每个代码中真正发生的事情方面有点慢。您添加 cmets 并给出恰当的解释确实有助于理解背后的逻辑,对此我非常感激。但是我有一个小问题..你能告诉你为什么在代码中使用 x[:] - emp_row = x[:]
  • 呵呵,我想知道你是否明白这一点;) 在 Python 中,列表是通过引用而不是值传递的,这可能会导致错误的意外 (*.com/a/2612815/246801)。我不确定在这种情况下是否完全有必要,但我认为制作显式列表副本并没有错。而且,我很高兴 cmets 提供了帮助,干杯!
  • 啊,是的,要制作一个明确的列表副本。我只学会了使用 .copy() 方法来制作它。每天都在学习新事物:)再次非常感谢您:D