【问题标题】:How to ignore empty values in csv file and continue in Python如何忽略 csv 文件中的空值并在 Python 中继续
【发布时间】:2018-10-18 10:01:25
【问题描述】:

我有两个示例 csv 文件,csvexample.csv 看起来像这样:

ID Text  
1  'good morning'  
2  'good afternoon'  
3  'good evening'  

虽然 csvexample1.csv 看起来像这样:

Day Month  
14  'Feb'  
21  'Mar'  
31  'May' 

通过以下代码,我得到了我想要的结果,即将 csvexample.csv 的第一列和 csvexample1.csv 的第二列添加到一个列表中;水库

import csv

res = []
with open('csvexample.csv') as f, open('csvexample1.csv') as a:
    reader=csv.reader(f) 
    reader1=csv.reader(a)
    next(reader)
    next(reader1)
    for row in zip(reader, reader1):
        res.extend([row[0][0], row[1][1]])  

print(res)   

我得到以下结果:

['1', 'Feb', '2', 'Mar', '3', 'May']  

但是,我想应用此代码以包含一些空单元格的实际 csv 文件,因为我正在将来自一个文件的公司的 Twitter 生物和来自另一个文件的这些公司的推文添加到一个列表中,但是有些公司在 Twitter 上没有个人简历,因此特定列中的那些单元格是空的。此外,在大多数情况下,第一个文件的行数比第二个文件少得多,但是当第一个文件没有剩余行并忽略第二个文件中的所有其他行时,结果似乎停止了。例如,如果我像这样编辑 csvexample.csv:

ID Text   
1  'good morning'  
2  'good afternoon'   

3  'good evening'  
4  

和 csvexmple1.csv 像这样:

Day Month  
14  'Feb'  
21     
31  'May'  

我得到以下结果:

['1', 'feb', '2', '', '', 'may']  

而不是期望的结果:

['1', 'feb', '2', '', '', 'may', '4']

我尝试了很多不同的东西,但我真的无法将其编辑为所需的结果。

from itertools import zip_longest
from io import StringIO
import csv

mystr1 = StringIO("""ID Text
1 'good morning'
2 'good afternoon'

3 'good evening'
4
""")

mystr2 = StringIO("""Day Month
14 'Feb'
21
31 'May'
""")

res = []
with mystr1 as f, mystr2 as a:


    reader = csv.reader(f, delimiter=' ')
    reader1 = csv.reader(a, delimiter=' ')

    next(reader)
    next(reader1)

for row in zip_longest(reader, reader1, fillvalue=''):
    var1 = row[0][0] if len(row[0]) else ''
    var2 = row[1][1] if len(row[1]) else ''
    res.extend([var1, var2])

print(res)

这个例子给了我以下错误:Traceback (most recent call last): File "thesis.py", line 31, in <module> var2 = row[1][1] if len(row[1]) else '' IndexError: list index out of range

【问题讨论】:

  • 也许在您的循环中,您可以先检查 row[0]row[1] 的值,并且只有当它们都存在时,您才能更新您的 res 变量。
  • zip 停在最短迭代器的末尾。你应该使用itertools.zip_longest

标签: python csv


【解决方案1】:

您可以使用itertools.filterfalse 删除空白行。这些行将以\n 开头并且可以相应地识别。

from itertools import zip_longest
from io import StringIO
import csv

mystr1 = StringIO("""ID Text
1 'good morning'
2 'good afternoon'

3 'good evening'
4
""")

mystr2 = StringIO("""Day Month
14 'Feb'
21
31 'May'
""")

res = []

with mystr1 as f, mystr2 as a:


    reader = csv.reader(f, delimiter=' ')
    reader1 = csv.reader(a, delimiter=' ')

    next(reader)
    next(reader1)

    for row in zip_longest(reader, reader1, fillvalue=''):
        try:
            var1 = row[0][0]
        except IndexError:
            var1 = ''
        try:
            var2 = row[1][1]
        except IndexError:
            var2 = ''
        res.extend([var1, var2])

print(res)

['1', "'Feb'", '2', '', '', "'May'", '3', '', '4', '']

【讨论】:

  • 我复制了这个确切的代码,但它给了我与我之前的代码相同的结果。我仍然得到 ['1', 'feb', '2', '', '', 'may'] ,所以在有一个空白行后它仍然停止读取行。
  • @NienkeLuirink,此更新可能会对您有所帮助。您可以使用很多技巧:zip_longest 以确保您使用两个文件中最长的一个,三元 if / elselen 以确保您不会得到 IndexError 等。跨度>
  • 将 zip 的输出解压缩到两个单独的变量中,而不是双重索引到重载的row,可能也更具可读性
  • @avigil,谢谢,好点子。我认为这涵盖了 OP 想要的所有内容,但仍不确定。
  • @jpp 非常感谢你的帮助,不知何故我仍然收到Traceback (most recent call last): File "new.py", line 30, in &lt;module&gt; res.extend([row[0][0] if len(row[0]) else '', row[1][1] if len(row[1]) else '']) IndexError: list index out of range
猜你喜欢
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多