【问题标题】:Reading columns of a csv file with python用python读取csv文件的列
【发布时间】:2011-07-30 17:18:26
【问题描述】:

我正在使用 python 的 CSV 模块来遍历列的行。

我需要做的是:

  1. 获取“title”列的第一行
  2. 删除所有西班牙语字符(重音,Ñ)
  3. 删除单引号
  4. 最后,用破折号替换空格并将所有内容转换为小写。

我让它与一个简单的测试文件一起工作,而不是一个 csv。我还设法将每个标题打印在它自己的单独行中。

但现在我正在使用这段代码来检查 CSV 文件(对不起,非常丑陋的代码,我是新手程序员):

import csv
import unicodedata
import ast

def strip_accents(s):
  return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))

dic_read = csv.DictReader(open("output.csv", encoding = "utf8"))

for line in dic_read:

    #print(line)     #I get each line of the csv file as a dictionary.
    #print(line["title"])  # I get only the "title" column on each line

    line = line.replace(' ', '-').lower()
    line = line.replace("´", "")
    line = strip_accents(line)
    fp=open("cleantitles.txt", "a")
    fp.write(line)
    fp.close()

我收到以下错误:

Traceback (most recent call last):
  File "C:/csvreader3.py", line 15, in <module> line = strip_accents(line)
 File "C:/csvreader3.py", line 7, in strip_accents
  return ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
  TypeError: must be str, not dict

当我尝试仅执行 .replace 时,我也会遇到类似的错误。我现在明白这些方法只适用于字符串。

我怎样才能让它工作?我四处寻找将 dict 转换为字符串对象的方法,但没有奏效。

此外,也欢迎任何对优化和使我的代码更具可读性的批评!

【问题讨论】:

  • 你到底想在这里做什么?读入一个 csv 文件,将所有“标题”条目修改为您想要的格式,然后将修改后的标题列与同一行输出到一个新文件中?
  • 没错。我实际上让我的脚本读取所有标题条目,但由于我找不到将这些作为字符串处理的方法,我不得不将所有标题条目输出到一个新的文本文件,然后将此文本文件处理到另一个新的,最终文本文件。效率不是很高,但我最终得到了结果。

标签: python csv


【解决方案1】:

有了手头的新信息,我想您可能会发现这种方法更简单。

使用内置函数“地图”。我将把“map”的作用的解释留给 python 文档。

这是我认为你应该做的事情

创建一个函数,该函数接受一行/字典并将其处理为您想要的格式

def strip_unwanted(line):
    title = str(line['title']).replace(' ', '-').replace("´", "")
    title = ''.join((c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn'))
    line['title'] = title
    return line

with open("output.csv", encoding = "utf8") as input:
    dic_entries = csv.DictReader(input)
    # use the 'map' function
    new_entries = map(strip_unwanted, dic_entries)

    with open('some.csv', 'wb') as output:
        writer = csv.DictWriter(output)
        writer.writerows(new_entries)

【讨论】:

    【解决方案2】:

    line 是一个字典。可能您想在line['title'] 上致电replace

    【讨论】:

    • 我试过line = line['title'].replace("´", "") 并得到了这个错误TypeError: string indices must be integers
    • 你的 csv 文件的第一行是什么?
    • DictReader 使用 CSV 文件的第一行形成 dict line 的键,除非另外指定键。见doughellmann.com/PyMOTW/csv
    • 是的,这可以解释为什么 "line = line['title'].replace("´", "")" 如果第一行没有列标题的分隔列表,或者缺少标题“标题”。否则我会说你的答案是正确的。
    • @james-hurford 是的,CSV 文件的第一行包含每一列的标题。我实际上设法让它打印我想要的列的键值。问题是我无法将值修改为字符串。
    【解决方案3】:

    当你对一个函数有问题时,试着让它输出一些东西,而不是试图返回它。这样,您可以验证它是否有效并隔离问题。一行中有太多语句。这使得很难知道问题出在哪里。你知道什么是字典吗?当然,没有直接的方法可以将 dict 转换为字符串。您需要找出要保留的数据。

    另外,您的意思是要进行列表理解吗?那么你应该使用方括号。

    【讨论】:

    • 是的,我确实设法使用 print(line) 打印出每个字典。请参阅我注释掉的代码。我不确定您提到的列表理解部分。我只是想在字典中获取title 的值。
    • 列表解析中使用的方法不必在方括号内完成,RafaelM 在这种情况下所做的完全正确。尝试执行 (x for x in range(10) if x % 2 == 0) 看看你会得到什么。
    • 我刚刚明白@Ysangkok 的意思。实际问题不在于 strip_accents() 函数,问题在于该函数或 .replace 不适用于 dicts。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2019-03-09
    • 2015-10-25
    相关资源
    最近更新 更多