Python:将列表保存在没有引号的文件中?

时间:2017-06-21 20:45:12

标签: python list csv python-2.x tab-delimited-text

我正在使用csv模块处理几个文本文件,我遇到了一些我无法理解的奇怪事件。到目前为止我的代码:

import csv

with open('file1.txt', 'r') as a:
    with open('file2.txt', 'w+') as b:
        reader = csv.reader(a, delimiter = '\t')
        writer = csv.writer(b, delimiter = '\t', quoting = csv.QUOTE_NONE, escapechar = '')

        for row in reader:
            # Do stuff

            writer.writerow(row)

            # Check datatypes of each column
            print(type(row))
            print(type(row[0]))
            print(type(row[1]))
            print(type(row[2]))
            print(type(row[3]))
            print(type(row[4]))
            print(row)

输出:

<type 'list'>
<type 'str'>
<type 'str'>
<type 'list'>
<type 'str'>
<type 'list'>
['blah', 'blah', ['01', '02', '03', '04'], 'blah', ['0', '0', '0', '0']]

我很高兴,直到我再次打开file2.txt进行进一步处理,但我不能,因为我得到了令人困惑的结果,所以我再次检查了类型,这次输出是不同的。

with open('file2.txt', 'r+') as c:

    reader = csv.reader(c, delimiter = '\t')

    for row in reader:
        print(row)
        print(type(row))
        print(type(row[0]))
        print(type(row[1]))
        print(type(row[2]))
        print(type(row[3]))
        print(type(row[4]))

输出:

['blah', 'blah', "['01', '02', '03', '04']", 'blah', "['0', '0', '0', '0']"]
<type 'list'>
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>

注意第3和第5个值的双引号。这些值是如何转换为字符串的?这对我来说很奇怪。我真的需要将第3列和第5列作为列表类型而不是字符串才能进一步处理它。

我的问题是如何将第3和第5列值转换回列表类型,或者更好的是如何防止它们首先保存为字符串?

如果我需要进一步澄清我的问题,请告诉我,请帮助我处理这种情况。

编辑:所以,我已经知道不可能阻止这些值存储为字符串,所以我现在正在考虑是否可以将这些值作为列表来处理。我真的不在乎如何将值存储在文件中,只要我将它们作为列表进行处理。

4 个答案:

答案 0 :(得分:0)

您无法阻止它们被保存为字符串。显然,CSV是一个文本文件;它对列表一无所知。传递给csv.writerow的任何内容都将通过调用str()转换为字符串。如果结果字符串包含逗号,则它本身将被引用,以便逗号显然是元素的一部分,而不是表示新元素的分隔符。

无法自动转换回列表。如果您知道每行的第2列应该是一个列表,您可以手动将其转换回来 - 执行此操作的一种方法是使用ast.literal_eval

答案 1 :(得分:0)

为什么不使用Pandas DataFrame课呢?它可以更好地覆盖不同的CSV规范,并且可以更好地控制各个列的数据类型。检查此link。您可以阅读CSV,然后非常容易地使用另一个分隔符写入另一个CSV。

答案 2 :(得分:0)

我认为你需要压扁你的行,以便在一个列表中转换列表列表。

以下是一个例子:

def flatten(seq):
    result = []
    for item in seq:
        if isinstance(item, list):
            result.extend(item)
        else:
            result.append(item)
    return result

简单用法:

row = ['blah', 'blah', ['01', '02', '03', '04'], 'blah', ['0', '0', '0', '0']]
row = flatten(row)
# -> ['blah', 'blah', '01', '02', '03', '04', 'blah', '0', '0', '0', '0']

我会纠正你这样的代码:

import csv

with open('file1.txt', 'r') as a:
    with open('file2.txt', 'w+') as b:
        reader = csv.reader(a, delimiter = '\t')
        writer = csv.writer(b, delimiter = '\t', quoting = csv.QUOTE_NONE, escapechar = '')

        for row in reader:
            # Do stuff

            writer.writerow(flatten(row))

答案 3 :(得分:0)

使用pickle,您可以将对象(在本例中为list)保存为序列化字节流,然后可以将其加载回并将该字节流重新转换为python对象。

这是一个如何运作的例子。

import pickle
writer = ['foo', 'bar', ['foo', 'bar'], 2]
pickle.dump(writer, open('file2.p', 'wb'))

如果您使用pickle加载file2.p,它将会重新转换为其原始对象:

writer = pickle.load(open('file2.p', 'rb'))
print(writer)

给出,

['foo', 'bar', ['foo', 'bar'], 2]

修改

创建writer

import csv
writer = []
with open('file1.txt', 'r') as a:
    reader = csv.reader(a, delimiter = '\t')
    for row in reader:
        writer.append(row)