在python中解析csv并在其他csv中编写,是,存在选择,如果没有选择,则否

时间:2019-03-11 14:04:55

标签: python csv parsing

输入(new.csv:)

student Jack

Choice Phy

Choice Chem

Choice  Maths

Choice  Biology

student Jill

Choice  Phy

Choice  Biology

Choice  Maths

预期输出(out.csv

Student  Phy     Chem   Maths   Biology

Jack     Yes     Yes      Yes   Yes

Jill    Yes      No       Yes   Yes

解析new.csv并将结果写在out.csv中。对于每个学生姓名,如果存在选择的主题,则写YES;如果主题不存在,则写NO。选择(主题成为out.csv中的新头)。 在这里,我使用nested if获得所需的输出。请以更好的pythonic代码方式帮助我。 我是python的新手,渴望学习更好的编码方式。 附注:主题的选择顺序不同。

import csv
la =[]
l2=[]
with open("new.csv","r",newline='\n') as k:
     k=csv.reader(k, delimiter=',', quotechar='_', quoting=csv.QUOTE_ALL)
     counter = 0
     for col in k :
           # number of rows in csv is 600      
            if counter<=600:

                if col[0] =='student':

                        la.append("\n "+col[1])
                        a=next(k) 


                       if a[1] == 'Phy':
                            la.append('yes')
                            a = next(k)

                        else:
                            la.append('no')

                        if a[1] == 'Chem':
                             la.append('yes')
                             a = next(k)
                        else:
                             la.append('no')

                        if a[1] == 'Maths':
                           la.append('yes')
                           a = next(k)
                        else:
                             la.append('no')

                        if a[1] == 'Biology':
                            la.append('yes')
                            a = next(k)
                            counter += 1

                        else:
                            la.append('no')
                            counter += 1        

l2=",".join(la)

with open("out.csv","w") as w:
    w.writelines(l2) 

1 个答案:

答案 0 :(得分:0)

恕我直言,现在该学习如何调试简单的程序了。某些IDE附带了不错的调试器,但您仍然可以使用旧的pdb或仅在代码中添加打印跟踪以轻松了解会发生什么。

这里,第一个也是最明显的问题是

tot = sum(1 for col in k)

这几乎没有用,因为for col in k就足够了,但是它消耗了k迭代器的全部内容,因此下一行for col in k:尝试访问已经达到其迭代器的迭代器结束,循环立即停止。

那还不是全部:

  • 第一行包含Student,大写字母S,而您测试student的小写字母s:它们是不同的字符串...这种情况下存在问题所有其他比较。
  • 找到student时,请将a设置在其后面的行上...永远不要更改它。因此,即使您解决了案例错误,您也将始终为学生使用该行!

如果您是初学者,则规则为保持简单,愚蠢。因此,从您可以控制的东西开始,然后开始添加其他功能:

  1. 使用csv模块读取输入文件,然后仅打印每行的列表。在提供所需内容之前,请不要进一步。那会让您摆脱tot = sum(1 for col in k)错误...
  2. 识别每个学生。只需先打印它,然后将其名称存储在列表中,然后在循环后打印列表即可。
  3. 确定主题。只需先打印它们,然后再给主题添加字典
  4. 想知道如何在循环结束时得到它...
  5. 只要意识到您可以将学生姓名存储在该词典中,然后将完整词典放在列表中即可(如果您被困在那里,可以随时问一个新问题...)
  6. 在循环结束时打印字典列表
  7. 为学生建立一行以供csv编写器使用,或者因为您已经有字典的清单,请考虑使用DictWriter

实践Python祝您好运!


这是阅读部分的一种可能方法:

import csv

la = {}       # use a dict to use the student name as index

with open("new.csv","r",newline='\n') as k:
    k=csv.reader(k, delimiter=',', quotechar='_', quoting=csv.QUOTE_ALL)
    # counter = 0 # pretty useless...
    for col in k :
        if col[0] =='student':
            l2 = set()        # initialize a set to store subjects
            la[col[1]] = l2   # reference it in la indexed by the student's name
        else:                 # it should be a subject line
            l2.add(col[1])    # note the subject

# Ok la is a dict with studend names as key, and a set containing subjects for that student as value
print(la)

对于书写部分,您应该:

  • 构建所有集合的并集以获取所有可能的主题(除非您知道)
  • 为la中的每个项目(名称,主题),建立一个列表,为每个可能的主题存储是或否。
  • 将该列表写入输出的csv文件

...作为练习...