【问题标题】:Filter() on DictReaderDictReader 上的 Filter()
【发布时间】:2014-05-28 16:08:32
【问题描述】:

我是 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'

请注意,我不想过滤文件指针 (e.g. here),而是过滤已解析的 csv 行。你知道怎么做吗?

【问题讨论】:

  • 这里的filteredReader 是什么?什么是完整的追溯?使用dialect时,不需要传入3个None参数,直接使用csv.DictReader(f, dialect=dialect)即可。
  • 至于你贴的异常,这里贴的代码是不能引发的;看起来好像您将reader 传递给os.path.normcase() function 或其他东西。 fr = filteredReader() 行在这里完全是一个红鲱鱼;你甚至没有使用那个对象。
  • 很抱歉给您带来了困惑。我的问题无效,其他代码段引发了错误。

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


【解决方案1】:

是的,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'}

【讨论】:

    【解决方案2】:

    使用 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

    【讨论】:

      猜你喜欢
      • 2022-12-27
      • 2016-03-28
      • 2014-03-01
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2014-11-11
      相关资源
      最近更新 更多