在DictReader上过滤()

时间:2014-04-14 15:47:53

标签: python csv python-3.x filter iteration

我是python的新手,并尝试理解如何在csv.DictReader上使用过滤器函数来过滤csv文件中的行。 filter()可用于“可迭代”,据我所知,DictReader符合此definition

然而,当我尝试

f = open('file1.csv', 'r')       
dialect = csv.Sniffer().sniff(f.read(1024))
f.seek(0)
reader = csv.DictReader(f, None, None, None, dialect)

filteredReader = filter(None, reader) #None will be replaced with my function
for i in filteredReader:
    print(i)

我得到TypeError: normcase() argument must be str or bytes, not 'DictReader'

请注意,我不想在filepointer(e.g. here)上过滤,而是在解析的csv行上过滤。你知道怎么做吗?

2 个答案:

答案 0 :(得分:2)

是的,DictReader()可以用作可迭代的,并且可以与filter()一起使用。

filter()函数依次传递给每一行(字典),如果函数返回该行的True,则传递给它:

>>> from io import StringIO
>>> import csv
>>> demo = StringIO('''\
... foo,bar,baz
... 42,88,131
... 17,19,23
... ''')
>>> reader = csv.DictReader(demo)
>>> def only_answers(row):
...     return '42' in row.values()
... 
>>> for row in filter(only_answers, reader):
...     print(row)
... 
{'baz': '131', 'bar': '88', 'foo': '42'}

答案 1 :(得分:0)

过滤器可以像您期望的那样使用DictReader。

假设你有这个csv文件:

numeral, English, Spanish
1, one, uno
2, two, dos
3, three, tres
4, four, quatro
5, five, cinco

(注意第2栏和第3栏中的前导空格)

你只想要奇数行:

>>> with open('/tmp/nums.csv') as f:
...      print filter(lambda d: int(d['numeral'])%2, csv.DictReader(f))
[{' English': ' one', 'numeral': '1', ' Spanish': ' uno'}, {' English': ' three', 'numeral': '3', ' Spanish': ' tres'}, {' English': ' five', 'numeral': '5', ' Spanish': ' cinco'}]

请注意,前导空格来自我们的数据。好的,以这种方式尝试csv.Sniffer

with open('/tmp/nums.csv') as f:
    dialect = csv.Sniffer().sniff(f.read(1024))
    f.seek(0)
    print filter(lambda d: int(d['numeral'])%2, csv.DictReader(f, dialect=dialect)) 
# [{'numeral': '1', 'Spanish': 'uno', 'English': 'one'}, {'numeral': '3', 'Spanish': 'tres', 'English': 'three'}, {'numeral': '5', 'Spanish': 'cinco', 'English': 'five'}]

好的,sniffer成功找到在方言中使用skipinitialspaces