【问题标题】:Write to csv: columns are shifted when item in row is empty (Python)写入 csv:当行中的项目为空时,列移动(Python)
【发布时间】:2013-08-10 09:20:21
【问题描述】:

基本阅读,一切正常:

with open('kres.csv', newline='') as f:
    reader = csv.reader(f, quoting=csv.QUOTE_ALL)
    for row in reader:
        print(row)
        kres.append(row)

我在这里写入 csv,但是当行中的字段(项目)为空时,列会移动,这是(我假设)因为程序不知道文件中有多少列并一一写入。
但我希望它不要跳过空白字段,我希望它写一些默认字符或无。我不知道如何检查字段是否为空。

with open('kres2.csv', 'w', newline='') as f:    # Just use 'w' mode in 3.x
    writer = csv.writer(f)
    writer.writerows(kres)

Windows 7 上的 Python 3.3.2

编辑: 试图 chak 列表中的每个字段,但不工作

with open('article_all_krestianin_ru.csv', newline='') as f:
    reader = csv.reader(f, quoting=csv.QUOTE_ALL)
    for row in reader:
        for i in row:
            if i == '':
                i = '-'
            print(row)
        krestianin.append(row)

编辑 2: ['А теперь - про язык;Окт 21', ' 2008;Окт 21', ' 2008А теперь - про язык спрашивала', 'как ;http://www.krestianin.ru/articles/5541.php']

这是来自控制台,所有 4 个项目都已到位(分隔符;)。这些项目中的任何一个都可能丢失,一个甚至两个,所以如果丢失 4 个中的 2 个,我想在它们的位置上加上“-”

【问题讨论】:

  • 我认为您需要更改实际的 CSV 文件,而不是代码
  • @ton1c 这是一个选项,当然,你认为现在有办法在代码中做到这一点吗?
  • 如果您知道行中应该有多少元素,以及应该在哪里,那么您只需将其他元素添加到您的 kres 列表中。或者您可以读取 CSV 文件,并在需要时将“空元素”添加为 -(某事、某事、-、 某事)
  • 您的 CSV 文件中没有空元素。如果您愿意,那么您的代码将跳过空列。所以你更新的这段代码是没用的。尝试发布您从文件中读取的实际完整行。
  • 您可以检查的唯一元素是最后一个(链接),只需使用正则表达式即可。我说俄语,这些信息没有任何意义或顺序。你不能检查它。

标签: python csv export-to-csv


【解决方案1】:

我认为您不了解 CSV 模块在 Python 中的工作原理。假设kres.csv 文件中有以下数据:

1,2,3,4,5,6,7
a,b,c,d,e,f,g

那么当你执行这段代码时:

import csv

kres = []

with open('kres.csv') as f:
    reader = csv.reader(f, quoting=csv.QUOTE_ALL)
    for row in reader:
        print(row)
        kres.append(row)

输出将是:

['1', '2', '3', '4', '5', '6', '7']
['a', 'b', 'c', 'd', 'e', 'f', 'g']

因此,您正在获取列表,每个列表都是您阅读的一行。

如果您的 kres.csv 文件中有这些数据:

1,2,3,5,6,7
a,b,c,d,e,f,g

你需要输出是这样的:

['1', '2', '3', '-', '5', '6', '7']
['a', 'b', 'c', 'd', 'e', 'f', 'g']

然后你需要写一个检查,首先检查行中有多少元素(在这种情况下,如果它小于 7,那么你错过了一些元素。之后你需要找到哪个元素是丢失。为此,您需要知道4(如本例所示)应恰好在3 之后和5 之前。

您可以使用 Regex 编写此检查(当然这取决于您在 CSV 文件中拥有的数据),并且您必须检查每个元素(是右侧列中的 elemtn,列表位置)。

您可以通过编程方式执行此操作,但不能使用 CSV 模块。


CSV 文件中的空元素如下所示:

1,2,3,,5,6,7
a,b,c,d,e,f,g

所以代码的输出将是:

['1', '2', '3', '', '5', '6', '7']
['a', 'b', 'c', 'd', 'e', 'f', 'g']

,,'', 是空元素

【讨论】:

  • 好的,你描述的很好,我可以使用 len(list) 来检查项目数。但是如何检查缺少什么?项目中的数据差异很大,所以没有办法使用正则表达式
  • print len(row) 会给你列表的长度。如果您无法检查该行,则无法执行此操作。只能手动。注册哪些行中缺少元素并通过比较输入和输出 CSV 文件手动编辑它们
  • 听起来不错,您可能需要自己检查缺少项目的行,并根据某些标准确定缺少的内容(这取决于您在 CSV 数据中期望的模式类型)。
  • 嗯,很奇怪:现在我检查了控制台输出和输出文件:有些项目没有丢失,但列移动了!顺便说一句:我的行列表中的某些项目没有像你的例子中那样引用'' - 这些项目丢失了
  • 因为您在 CSV 文件中没有它们...这就是我试图向您解释的...无论如何,正如我所说,尝试将数据重新抓取到 CVS 文件中,当你报废它时,只需检查一下:如果没有报废,则添加 - 而不是值。这将允许您在读取/写入 CSV 文件时保持列的结构
【解决方案2】:

在导出到 CSV 之前,您应该使用 None 值填充所有缺失的字段:

def normalizing_dict_list(list):
    """
    Fill all empty and missed dict keys. I.e.
    [{'bar':1, 'foo':2}, {'foo':10, 'baz':20}] converts to
    [{'bar':1, 'foo':2, 'baz':None},{'bar':None, 'foo':10, 'baz':20}]

    """
    # init key list
    keys_list=[]
    for asset in list:
        for key in asset.keys():
            # add new keys to list
            if not key in keys_list:
                keys_list.append(key)

    # init result list
    normal_dict=[]
    for asset in list:
        normal_asset={}

        # iterate every possible keys
        for key in keys_list:
            normal_asset[key]=asset.get(key)
        normal_dict.append(normal_asset)
    return normal_dict

以及出口清单

norm_list = normalizing_dict_list(list_with_missed_fields)

with open('export.csv', 'w',newline='') as out_csv:
        writer = csv.writer(out_csv)
        writer.writerow(norm_list[0].keys())
        for obj in norm_list:
            writer.writerow(obj.values())

【讨论】:

    【解决方案3】:

    无需更改代码 - 一切正常。 首先,我检测障碍物的类型是错误的:我认为它缺少字段,但这是 Excel 2010 默认打开设置。 简短回答: csv 正确 处理 ;;在文件中,列不移动。

    但列在 Excel 中默认打开时发生了移动: some ; Excel 2010 未正确识别,因此数据合并到第一列。 看起来像:'Some text;18.08.2009; - 第一;未检测到。

    如何正确导入:

    转到数据选项卡 2.选择从文件导入 3. 在导入向导中选择带分隔符的数据 4.接下来,选择;作为分隔符 5.这里是答案:默认情况下字符串是用"分割的,但是需要改成'

    【讨论】:

      猜你喜欢
      • 2021-05-04
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多