csv: writer.writerows() splitting my string inputs

后端 未结 4 866
予麋鹿
予麋鹿 2020-12-09 19:37

I have a list of strings which I would like to write to a csv file. The list list_results looks like

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


        
相关标签:
4条回答
  • 2020-12-09 20:19

    You are using writer.writerows() with an s at the end. That method expects a list of lists, but you passed in a list of strings. The writerows() method essentially does this:

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

    where each row must be a sequence of columns. A string is a sequence of individual characters, so that's what you get written: individual characters separated by your chosen delimiter.

    You'll need to split out your string into columns, don't include the commas yourself, it's the job of the writer object to include those:

    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)
    

    or using a generator expression so you can keep using 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)
    

    Demo:

    >>> 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
    
    0 讨论(0)
  • 2020-12-09 20:22

    writerows expects a list of lists. So if you give a list to writerows it will convert it into list of list ( i.e. fragmenting words into letters.

    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])
    

    Or if you want to use 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)
    

    Output-

    Correct?    Successes   Failures
    FALSE   60  40
    TRUE    70  30
    
    0 讨论(0)
  • 2020-12-09 20:33

    Most likely your list_results contains something like:

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

    writerows() takes a list of lists, you supply a list of strings, a string is iterable and is thus converted into list of chars, what you want is:

    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)
    
    0 讨论(0)
  • 2020-12-09 20:36

    it works fine:

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

    This is source code for writer.writerows() on C.

    
    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;
    

    }

    0 讨论(0)
提交回复
热议问题