将单个值更改/写入csv文件python

时间:2014-04-09 15:30:19

标签: python csv python-3.x export-to-csv

我的代码中有错误:

_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

2 个答案:

答案 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