【问题标题】:csv: writer.writerows() splitting my string inputscsv: writer.writerows() 分割我的字符串输入
【发布时间】:2016-03-21 00:04:53
【问题描述】:

我有一个要写入 csv 文件的字符串列表。列表list_results 看起来像

['False, 60, 40 ', 'True, 70, 30, ']

所以,我会尝试这样的事情:

with open('example1.csv', 'w') as result:
    writer = csv.writer(result, delimiter=",")
    writer.writerow( ('Correct?', 'Successes', 'Failures') )
    writer.writerows(list_results)

不幸的是,数据没有写入三列。我发现:

['Correct?', 'Successes', 'Failures']  
['F', 'a', 'l', 's', 'e', ',', ' ', '6', '0', ',', ' ', '4', '0', ' ']  
['T', 'r', 'u', 'e', ',', ' ', '7', '0', ',', ' ', '3', '0', ',', ' ']

如何适当地格式化此行为以获取

['Correct?', 'Successes', 'Failures']  
['False', 60, 40]  
['True', 70, 30]

最好采用%s %d %d 格式?

【问题讨论】:

    标签: python csv


    【解决方案1】:

    您使用的是writer.writerows(),末尾带有s。该方法需要一个列表列表,但您传入了一个字符串列表。 writerows() 方法本质上是这样做的:

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)
    

    其中每一行必须是一系列列。字符串是单个字符的序列,所以这就是您所写的:由您选择的分隔符分隔的单个字符。

    你需要将你的字符串分成几列,不要自己包含逗号,包含这些是 writer 对象的工作:

    with open('example1.csv', 'w') as result:
        writer = csv.writer(result, delimiter=",")
        writer.writerow(('Correct?', 'Successes', 'Failures'))
        for row in list_results:
            columns = [c.strip() for c in row.strip(', ').split(',')]
            writer.writerow(columns)
    

    或使用生成器表达式,以便您可以继续使用writerows()

    with open('example1.csv', 'w') as result:
        writer = csv.writer(result, delimiter=",")
        writer.writerow(('Correct?', 'Successes', 'Failures'))
        writer.writerows([c.strip() for c in r.strip(', ').split(',')]
                         for r in list_results)
    

    演示:

    >>> import csv
    >>> list_results = ['False, 60, 40 ', 'True, 70, 30, ']
    >>> import csv
    >>> import sys
    >>> list_results = ['False, 60, 40 ', 'True, 70, 30, ']
    >>> writer = csv.writer(sys.stdout)
    >>> writer.writerow(('Correct?', 'Successes', 'Failures'))
    Correct?,Successes,Failures
    >>> for row in list_results:
    ...     columns = [c.strip() for c in row.strip(', ').split(',')]
    ...     writer.writerow(columns)
    ...
    False,60,40
    True,70,30
    >>> writer.writerows([c.strip() for c in r.strip(', ').split(',')]
    ...                  for r in list_results)
    False,60,40
    True,70,30
    

    【讨论】:

    • 我收到columns = [c.strip() for c in result.split(',')] 的错误,即AttributeError: 'list' object has no attribute 'split'
    • @ShanZhengYang:那么您的list_results 不仅仅包含您在问题中声称的字符串。
    • @ShanZhengYang:该错误意味着您的list_result 元素中至少有一个 不是字符串而是列表。你能用你的所有数据更新你的问题吗?
    • 看起来是这样...['False, 60, 40 ', 'True, 70, 30, ']这是两个字符串的列表
    • @ShanZhengYang:使用该列表,您声称抛出的错误不会被抛出。
    【解决方案2】:

    您的list_results 很可能包含以下内容:

    ['False, 60, 40 ', 'True, 70, 30, ']
    

    writerows() 接受一个列表列表,你提供一个字符串列表,一个字符串是可迭代的,因此被转换为字符列表,你想要的是:

    with open('example1.csv', 'w') as result:
        writer = csv.writer(result, delimiter=",")
        writer.writerow( ('Correct?', 'Successes', 'Failures') )
        writer.writerows([c.strip() for c in r.split(',')] for r in list_results)
    

    【讨论】:

    • 我认为这是正确的,但我得到了一个错误。 list_results 是一个列表 writer.writerows([c.strip() for c in r] for r in list_results.split(',')) AttributeError: 'list' object has no attribute 'split'
    • 呵呵没有复制,只是犯了同样的错误。我现在已经确定了答案
    【解决方案3】:

    效果很好:

    list_results = [(False, 60, 40), (True, 70, 30)]

    这是 C 上 writer.writerows() 的源代码。

    
    static PyObject *
    csv_writerows(WriterObj *self, PyObject *seqseq)
    {
        PyObject *row_iter, *row_obj, *result;
    
    
    row_iter = PyObject_GetIter(seqseq);
    if (row_iter == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "writerows() argument must be iterable");
        return NULL;
    }
    while ((row_obj = PyIter_Next(row_iter))) {
        result = csv_writerow(self, row_obj);
        Py_DECREF(row_obj);
        if (!result) {
            Py_DECREF(row_iter);
            return NULL;
        }
        else
             Py_DECREF(result);
    }
    Py_DECREF(row_iter);
    if (PyErr_Occurred())
        return NULL;
    Py_INCREF(Py_None);
    return Py_None;
    

    }

    【讨论】:

      【解决方案4】:

      writerows 需要一个列表列表。所以如果你给writerows一个列表,它会将它转换为列表列表(即将单词分割成字母。

      import csv
      list_results = ['False, 60, 40 ', 'True, 70, 30, ']
      
      with open(r"C:\test.csv", 'wb') as result:
          writer = csv.writer(result, delimiter=",")
          writer.writerow( ('Correct?', 'Successes', 'Failures') )
          writer.writerows([i.strip().split(',') for i in list_results])
      

      或者如果你想使用writerow-

      import csv
      list_results = ['False, 60, 40 ', 'True, 70, 30, ']
      
      with open(r"C:\mnp_.csv", 'wb') as result:
          writer = csv.writer(result, delimiter=",")
          writer.writerow( ('Correct?', 'Successes', 'Failures') )
          data = [i.strip().split(',') for i in list_results]
          for d in data:
              writer.writerow(d)
      

      输出-

      Correct?    Successes   Failures
      FALSE   60  40
      TRUE    70  30
      

      【讨论】:

      • 这给了我 ['Correct?', 'Successes', 'Failures'] ['False, 60, 40', 'True, 70, 30, ']
      • 我能以某种方式正确解析此字符串以使其位于正确的列中吗?
      • @SIslam:那是废话。 OP 没有字典可以在这里写。
      • @ShanZhengYang:是的,您需要将字符串拆分为列。
      猜你喜欢
      • 1970-01-01
      • 2017-01-15
      • 2023-03-15
      • 2020-03-07
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多