我正在使用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列值转换回列表类型,或者更好的是如何防止它们首先保存为字符串?
如果我需要进一步澄清我的问题,请告诉我,请帮助我处理这种情况。
编辑:所以,我已经知道不可能阻止这些值存储为字符串,所以我现在正在考虑是否可以将这些值作为列表来处理。我真的不在乎如何将值存储在文件中,只要我将它们作为列表进行处理。
答案 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)