Python: 将列表保存在不带引号的文件中?
Python: Saving list in a file without quotes?
我正在使用 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 列的值转换回列表类型,或者如何更好地防止它们首先被保存为字符串?
如果我需要进一步澄清我的问题,请告诉我,请帮助我处理这种情况。
编辑: 所以,我了解到无法阻止将这些值存储为字符串,所以我现在在考虑是否可以开始工作这些值作为列表。我真的不在乎值是如何存储在文件中的,只要我将它们作为列表来处理即可。
您无法阻止将它们另存为字符串。显然,CSV 是一个文本文件;它对列表一无所知。传递给 csv.writerow
的任何内容都将通过调用 str()
转换为字符串。如果生成的字符串包含逗号,它本身将被引用,以便很明显逗号是元素的一部分,而不是表示新元素的分隔符。
无法自动转换回列表。如果您知道每一行的第 2 列应该是一个列表,您可以手动将其转换回来 - 一种方法是使用 ast.literal_eval
.
为什么不使用 Pandas DataFrame
class 呢?它更好地覆盖了不同的 CSV 规范,并且更好地控制了各个列的数据类型。检查此 link。您可以读取 CSV,然后使用另一个分隔符非常轻松地写入另一个 CSV。
我认为您需要展平您的行,以便在单个列表中转换列表列表。
这是一个例子:
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))
使用 pickle
您可以将对象(在本例中为列表)保存为序列化字节流,然后您可以将其加载回去并将该字节流重新转换为 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)
我正在使用 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 列的值转换回列表类型,或者如何更好地防止它们首先被保存为字符串?
如果我需要进一步澄清我的问题,请告诉我,请帮助我处理这种情况。
编辑: 所以,我了解到无法阻止将这些值存储为字符串,所以我现在在考虑是否可以开始工作这些值作为列表。我真的不在乎值是如何存储在文件中的,只要我将它们作为列表来处理即可。
您无法阻止将它们另存为字符串。显然,CSV 是一个文本文件;它对列表一无所知。传递给 csv.writerow
的任何内容都将通过调用 str()
转换为字符串。如果生成的字符串包含逗号,它本身将被引用,以便很明显逗号是元素的一部分,而不是表示新元素的分隔符。
无法自动转换回列表。如果您知道每一行的第 2 列应该是一个列表,您可以手动将其转换回来 - 一种方法是使用 ast.literal_eval
.
为什么不使用 Pandas DataFrame
class 呢?它更好地覆盖了不同的 CSV 规范,并且更好地控制了各个列的数据类型。检查此 link。您可以读取 CSV,然后使用另一个分隔符非常轻松地写入另一个 CSV。
我认为您需要展平您的行,以便在单个列表中转换列表列表。
这是一个例子:
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))
使用 pickle
您可以将对象(在本例中为列表)保存为序列化字节流,然后您可以将其加载回去并将该字节流重新转换为 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)