我的代码中有错误:
_csv.Error: sequence expected
我认为是因为我只想写一个值而不是列表等。
exRtFile = open ('exchangeRate.csv')
exchReader = csv.reader(exRtFile)
exchWriter = csv.writer(exRtFile)
loop2=0
while loop2==0:
selected=int(input("Please select an option: "))
if selected == 1:
change = input("What rate would you like to change: ")
changeRt = float(input("What would you like to change the rate to: "))
for row in exchReader:
currency = row[0]
if currency == change:
crntRt = row[1]
crntRt = changeRt
exchWriter.writerow(crntRt)
exRtFile.close()
解决此问题的最佳方法是什么,或者更改CSV文件中的值是否更好?
csv文件:
Pound Sterling,1
Euro,1.22
US Dollar,1.67
Japanese Yen,169.948
答案 0 :(得分:2)
以下是一些未经测试的代码,可以执行您想要的操作。我们的想法是将文本读入内存,应用更新,然后在原始文件中写出结果。
您可以进一步增强此功能,询问用户是否要保存更改,并添加新货币,而不是仅仅告诉用户他们不知道。
在现实世界中,我会将这段代码分成三个独立的函数(甚至是类),一个用于读取,一个用于写入,另一个用于编辑列表。
import csv
rates = {}
# read file into dictionary
with open('csv_file.csv', 'r') as in_file:
rdr = csv.reader(in_file)
for item in reader:
rates[row[0]] = row[1]
# ask user for updates and apply to dictionary
while true:
cmd = raw_input('Enter exchange rate to adjust, or blank to exit')
if cmd is None or cmd.strip() == '':
break
if rates.has_key(cmd):
new_rate = float(raw_input('Enter new exchange rate:'))
rates[cmd] = new_rate
else:
print 'Currency {} is not known.'.format(cmd)
# Write the updated dictionary back over the same file.
with open('csv_file.csv', 'w') as out_file:
wrtr = csv_writer(out_file)
wrtr.writerows(rates)
答案 1 :(得分:1)
回答你的问题:是的,问题是你试图只写一个值,而writerow
需要一个列表。
那说......你会考虑改变代码的工作方式吗?
这就是我所做的(我现在已经测试过,所以我知道它有效):
dict
中,其中键是货币名称(例如 Euro ),值为新货币值(例如 5.0 )用户可以按0
exchangeRate.csv
文件。如果row[0]
(货币名称)是要更改的值之一,则在该行中更改它。exchangeRate.csv.tmp
exchangeRate.csv.tmp
一些行未更改且某些行已更改。将.tmp
文件交换(移动)到exchangeRate.csv
Dunno ......也许可能会有太大的变化?无论如何,这是:
import csv
import shutil
change_rates = {}
selected = 1
while selected:
selected=int(raw_input("Please select an option: (1 to change, 0 to exit)"))
if selected == 1:
change = raw_input("What rate would you like to change?: ")
changeRt = float(raw_input("What would you like to change the rate to: "))
change_rates[change] = changeRt
if len(change_rates) > 0:
with open('exchangeRate.csv', 'r') as f_in,\
open('exchangeRate.csv.tmp', 'w') as f_out:
exchReader = csv.reader(f_in)
exchWriter = csv.writer(f_out)
for row in exchReader:
if row[0] in change_rates:
row[1] = change_rates[row[0]]
exchWriter.writerow(row)
shutil.move('exchangeRate.csv.tmp', 'exchangeRate.csv')
下面的示例执行:
Please select an option: (1 to change, 0 to exit)1
What rate would you like to change?: Euro
What would you like to change the rate to: 5
Please select an option: (1 to change, 0 to exit)0
borrajax@borrajax:~/Documents/Tests$ cat ./exchangeRate.csv
Pound Sterling,1
Euro,5.0
US Dollar,1.67
Japanese Yen,169.948
您可以随时进行更多优化,例如...允许不区分大小写的搜索,或检查货币是否实际已更改(即使用户说他想要更改货币 Euro 到 5.0 ,如果这是欧元的汇率那么就什么都不做了...... ......就是这样。
编辑1 :
我刚刚见过Larry Lustig的answer并且我同意对于小文件,因为它似乎是你的情况(你可以在内存中完全加载的文件)从我发布的磁盘连续读取和写入不是最佳。他将所有内容保存在内存中然后批量写入同一exchangeRate.csv
文件的想法可能更适合您的需求。
编辑2 :
在对此答案的评论中回答您的问题:
.tmp在结束时做了什么:exchangeRate.csv.tmp:
这只是一个新名字。我添加后缀.tmp
以避免与原始文件(exchangeRate.csv)的命名冲突。你可以随意命名(即使foobar.baz
)
变量中'更改'的目的是什么:change_rates [change] = changeRt:
change
是一个包含要更改的货币名称的变量(在我发布的用法示例中,change
包含字符串"Euro"
,因为这就是用户(嗯。 .. me)在控制台上键入。只是访问dict的一种方式。
'[row [0]]'的作用是什么:row1 = change_rates [row [0]]。
我们同意,在阅读文件时,row[0]
(就像那样,而不是[row[0]]
)包含文件中的货币名称( Euro,Pound Sterling ...... etcetera)对吧?因此,在执行的某个时刻row[0]
将包含字符串"Euro"
,其中(在我的测试示例中)是用户想要更改的货币。该字符串("Euro"
)也是change_rates
字典中的一个键(因为用户说他想要更改它),因此您要查询项目的值 < "Euro"
词典中的strong>键 change_rates
(将为您提供5.0
)。几乎正在做change_rates["Euro"]
要更清楚地看一下print "Currencies to change: %s" % change_rates
,请在if len(change_rates) > 0:
上方的行上添加exchangeRate.csv
行(这将向您显示字典的外观)
shutil.move('exchangeRate.csv.tmp','exchangeRate.csv')做了什么?
它将使用新币种的文件复制到{{1}}(请参阅shutil documentation)