我试图解决一个问题,pyschools网站要求编写一个脚本,读取一个以逗号", "作为分隔符的CSV文件并返回一个记录列表。当在他们的网站上运行我的脚本时,使用测试用例:csvReader('books.csv')[0]返回不正确的结果,从而返回:
['"Pete,Zelle","Intro to HTML, CSS",2011']
当预期的结果是:
['Pete,Zelle', 'Intro to HTML, CSS', '2011']
我注意到这个问题与引号"& '有关,但仍然没有找到正确的答案,使用replace('"','')来删除行变量中的双引号并不能解决这个问题,因为它返回的是:
['Pete,Zelle,Intro to HTML, CSS,2011']
其中它删除了一些单词的最后一个引号,例如Zelle,而不是Zelle',。
下面将提供练习、问题和我当前脚本的链接。任何解释或帮助都是非常感激的。
链接。http:/www.pyschools.comquizview_questions13-q8
问题:写一个函数来读取一个以','作为分隔符的CSV文件,并返回一个记录列表.该函数必须能够忽略双引号'"内的','。
脚本。
def csvReader(filename):
records = []
for line in open(filename):
line = line.rstrip() # strip '\n'
if line=='","':
continue # ignore empty line
records.append([line.replace('"','')])
return records
我是在你试图读取的CSV文件之后。听起来你需要将字段分开,同时忽略引号之间的任何定界符。
在这种情况下,我建议使用CSV库并设置引号字符。
import csv
record = '"Pete,Zelle","Intro to HTML, CSS",2011'
newStr = [ '"{}"'.format(x) for x in list(csv.reader([record], delimiter=',', quotechar='"'))[0] ]
print(newStr)
将返回['"Pete,Zelle"', '"HTML, CSS介绍"', '"2011"']。
在你的功能中,你可以加入以下内容
import csv
def csvReader(filename):
records = []
for line in open(filename):
line = line.rstrip() # strip '\n'
if line=='","':
continue # ignore empty line
newLine = [ '"{}"'.format(x) for x in list(csv.reader([line], delimiter=',', quotechar='"'))[0] ]
records.append(newLine)
return records
电池照例是包含在python中的。这里使用的是标准的lib csv模块。
import csv
with open(path, "r") as f:
csv_reader = csv.reader(f, delimiter=",")
for row_number, row in enumerate(csv_reader):
print(f"{row_number} => {row}")
如果stdlib因为一些奇怪的原因不能使用 你需要用 "分隔符","分隔符 "和 "单元格值 "来标记每一行。同样,这在stdlib中也是很简单的。import re
). 让我们假设你没有电池,只需要 plain python
.
你需要意识到,如何处理每一行的每个字符取决于 "上下文",而这个上下文是由前面所有字符建立起来的。这里建议使用堆栈。根据当前的上下文(堆栈的顶部)和当前的字符,你可以从堆栈中推送和弹出状态(也就是上下文)。现在,给定一个上下文,你可以根据上下文处理每个字符。
class State:
IN_NON_DELIMITED_CELL = 1
IN_DELIMITED_CELL = 2
def get_cell_values(line, quotechar='"', separator=','):
stack = []
stack.append(State.IN_NON_DELIMITED_CELL)
cell_values = [""]
for character in line:
current_state = stack[-1]
if current_state == State.IN_NON_DELIMITED_CELL:
if character == quotechar:
stack.append(State.IN_DELIMITED_CELL)
elif character == separator:
cell_values.append("")
else:
cell_values[-1] += character
if current_state == State.IN_DELIMITED_CELL:
if character == quotechar:
stack.pop()
else:
cell_values[-1] += character
return cell_values
with open(path, "r") as f:
for line in f:
cell_values = tokenize(line, quotechar='"', delimiter=',')
print(cell_values)
这是一个很好的出发点:
print(get_cell_values('"this","is",an,example,of,"doing things, the hard way?"'))
# prints:
['this', 'is', 'an', 'example', 'of', 'doing things, the hard way?']
要想更进一步,可以看看这些主题: 符号化字符串,LL+LR解析器,递归后裔,shift-reduce解析器。