如何将两个不同长度的列表写入CSV文件的列和行中

3

我有两个长度不同的列表:

list1 = ['a']
list2 = [['apple','banana','grapes']]

我希望在CSV文件中包含以下内容:
col1  col2
a     apple, banana, grapes

首先我尝试了 itertoolsizip,但是它似乎只将列表中的第一个元素放入了列表2的第二列,所以看起来是这样的:

col1  col2
a     apple

如何获取版本,包括list2中的完整列表作为行?
我使用以下代码将上述内容存储到csv文件中:
import csv
from itertools import izip

with open('some.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerows(izip(list1,sum(list2,[]))

1
CSV 中的逗号默认为分隔符,我担心你是否需要将 1,2,3,4 存储为 1;2;3;4"1,2,3,4"。你能否附上你用于写入 CSV 文件的代码片段? - ZdaR
@ZdaR 那我应该把 list2 转换成字符串吗? - halo09876
@ZdaR 我添加了代码,它只是使用 izip 将两个列表存储到 csv 中。 - halo09876
list1是否始终包含与list2相同数量的元素?list1中是否始终只有字符串,而list2中则始终只有数字列表? - Cleb
@Cleb 对于第一个问题,是的;对于第二个问题,不是——在我的实际数据中,两者都是字符串。 - halo09876
显示剩余2条评论
4个回答

2
izip 会将较长的列表截断以匹配较短的列表,因此 izip(['a'], ['a', 'b', 'c']) 实际上会返回 ['a', 'a'],这就是问题所在。
通常情况下,您应该使用 str.join() 来将列表转换为字符串,而不是使用 sum()
根据问题描述,我猜您需要一个由制表符分隔的 csv 文件。为了解决这个问题,首先将 list2 转换为字符串列表:
    >>> list2_str = [','.join(lst) for lst in list2]
    ['apple,banana,grapes']

然后将list1list2_str压缩成zip文件:

    >>> list3 = zip(list1, list2_str)
    [['a', 'apple,banana,grapes']]

打开一个csv写入器,使用“excel-tab”方言,并写入行:
    >>> writer = csv.writer(file, dialect='excel-tab')
    >>> writer.writerows(list3)

如果您想要使用逗号作为分隔符的csv文件,只需删除dialect参数即可。Python将正确引用第二列,生成:
    a,"apple,banana,grapes"

在csv文件中。


1
您可以使用pandas来执行类似以下操作:
list1 = ['a']
list2 = [['apple','banana','grapes']]
import pandas as pd
f = pd.DataFrame({'col1':list1, 'col2':list2})
f.to_csv('filename.csv', header=True, index=False)

0
正如评论中@ZdaR所指出的,逗号是.csv文件的默认分隔符,因此,将您的字符串用逗号分隔可能会导致混淆。相反,您可以使用分号来分隔您的字符串。
list1 = ['a', 'b']

list2 = [['apple','banana','grapes'], ['foo', 'bar']]

# convert all your lists of strings to single strings separated by a semicolon
list3 = [";".join(li) for li in list2]

list3 现在的样子如下:

['apple;banana;grapes', 'foo;bar']

现在你可以使用你的代码:

from itertools import izip
import csv

with open('some.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerows(izip(list1, list3))

这将会给你以下的输出

a   apple;banana;grapes
b   foo;bar

如果您想再次读取文件,可以使用例如pandas轻松完成此操作:
import pandas as pd
df = pd.read_csv('some.csv', header=None, names=['col1', 'col2'])

这将给你:

 col1                 col2
0    a  apple;banana;grapes
1    b              foo;bar

0

方法取决于你是只需要两列还是更多?

如果需要额外的列:

import csv
from itertools import izip

list1 = ['a', 'b']
list2 = [['apple','banana','grapes'], ['cherry']]

with open('some.csv', 'wb') as f:
    writer = csv.writer(f)
    writer.writerow(["col1", "col2"])

    for i1, i2 in izip(list1, list2):
        writer.writerow([i1] + i2)

这将会给你:
col1,col2
a,apple,banana,grapes
b,cherry

如果只需要两列,您可以切换到使用制表符作为分隔符,以允许逗号分隔list2条目:

import csv
from itertools import izip

list1 = ['a', 'b']
list2 = [['apple','banana','grapes'], ['cherry']]

with open('some.csv', 'wb') as f:
    writer = csv.writer(f, delimiter='\t')
    writer.writerow(["col1", "col2"])

    for i1, i2 in izip(list1, list2):
        writer.writerow([i1] + [', '.join(i2)])

这将会给你:
col1    col2
a   apple, banana, grapes
b   cherry

当再次读取csv文件时,这不会导致问题吗?当我尝试使用df=pd.read_csv('some.csv')时,生成的数据框看起来相当奇怪。你会如何读取你的csv文件? - Cleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接