通过Python向CSV文件添加数据
我有一个函数,可以把新数据添加到一个csv文件里。现在这个功能有点用,但我遇到了一些问题。
- 当我添加新的值
(name, phone, address, birthday)
时,它们都被放在了一列里,而不是同一行的不同列。(我其实不太知道怎么把它们分开到不同的列...) - 我只能添加数字,而不能添加字符串值。所以如果我写
add_friend(blah, 31, 12, 45)
,它会提示blah
没有定义。但是如果我写add_friend(3,4,5,6)
,它就会把这些数字加到新的一行里,但还是放在同一列。 - 这个函数的一个目标是:如果你尝试添加一个已经在csv里的朋友(比如,Bob),而他的地址、电话、生日已经在csv里了,如果你写
add_friend(Bob, address, phone, birthday)
,它应该返回False
,并且不添加这个朋友。但是,我完全不知道怎么实现这个功能。有什么想法吗?
这是我的代码:
def add_friend (name, phone, address, birthday):
with open('friends.csv', 'ab') as f:
newrow = [name, phone, address, birthday]
friendwriter = csv.writer(open('friends.csv', 'ab'), delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
friendwriter.writerow(newrow)
#friendreader = csv.reader(open('friends.csv', 'rb'), delimiter=' ', quotechar='|')
#for row in friendreader:
#print ' '.join(row)
print newrow
3 个回答
你没有说明自己对Python的熟悉程度,所以我会把内容讲得简单一些,没别的意思。
你的作业有几个“要求”。一般来说,你应该确保每个函数只做一件事。所以,为了满足所有要求,你需要写几个函数;可以考虑创建至少一个模块(也就是一个包含函数的文件)。
用空格作为分隔符和用
|
来表示引号,这种做法有点不常见。对于当前的文件,列与列之间的分隔符是什么?用什么来引用或转义文本?(这里的“转义文本”是指:如果我有一个用逗号作为列分隔符的csv文件,而我想在某一列中放一句带逗号的句子,我需要区分哪个逗号是“新列”的意思,哪个逗号是句子的一部分。微软决定Excel支持双引号,所以"hello, sailor"
就成了一个事实上的标准。)如果你想知道
"bob brown"
是否已经在文件中,你需要先读取整个文件,然后再尝试插入。你可以先用'r'
模式读取,然后用'w'
模式写入。但是每次想插入一条记录时都要读取整个文件吗?如果你有一百条记录要添加,是不是每次都要读取整个文件?有没有办法在添加过程中存储这些名字?blah
不是一个字符串。它需要用引号括起来才能成为字符串字面量("blah"
)。blah
只是指一个名为blah
的变量。如果提示blah
没有定义,那是因为你还没有声明这个变量来存储任何东西。
- 它并不是这样工作的。你为什么会觉得它是这样呢?可能你真正想要的引用方式并不是你给csv.writer指定的那种:也就是说,空格用来分隔列,而
|
是引用字符。 blah
不是字符串字面量,"blah"
才是。没有引号的blah
是一个变量引用,而这个变量在这里并不存在。- 要检查一个名字是否已经在CSV文件中,你必须先读取整个CSV文件,查看具体内容。打开文件两次:第一次是以读取模式(
'r'
)打开,然后用csv.reader将其转化为行迭代器,找到所有的名字。你可以把这些名字放到一个集合中,这样以后检查的时候就可以用这个集合了。
关于第3点:
要获得这个集合,你可以这样定义一个函数:
def get_people():
with open(..., 'r') as f:
return set(map(tuple, csv.reader(f)))
然后如果你把这个集合赋值给某个变量,比如existing_people = get_people()
,那么在添加新人的时候就可以用这个集合来检查,如下所示:
newrow = (name, phone, address, birthday)
if newrow in existing_people:
return False
else:
existing_people.add(newrow)
friendwriter.writerow(newrow)
根据你的需求,以及你似乎想要做的事情,我写了以下内容。希望能让你看得明白。
在读取CSV文件时,你需要保持分隔符和其他属性的一致性。
另外,尽量把 "friends.csv"
移到一个全局变量中,或者至少放在一个不是硬编码的常量里。
import csv
def print_friends():
reader = csv.reader(open("friends.csv", "rb"), delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
for row in reader:
print row
def friend_exists(friend):
reader = csv.reader(open("friends.csv", "rb"), delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
for row in reader:
if (row == friend):
return True
return False
def add_friend(name, phone, address, birthday):
friend = [name, phone, address, birthday]
if friend_exists(friend):
return False
writer = csv.writer(open("friends.csv", "ab"), delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
writer.writerow(friend)
return True
print "print_friends: "
print_friends()
print "get_friend: "
test_friend = ["barney", "4321 9876", "New York", "2000"]
print friend_exists(test_friend)
print "add_friend: "
print add_friend("barney", "4321 9876", "New York", "2000")