通过Python向CSV文件添加数据

3
我有一个函数用于向csv文件添加新数据,我已经让它在某种程度上工作。但是,我遇到了一些问题。
  1. 当我添加新值(姓名、电话、地址、生日)时,它会将它们全部添加到同一列中,而不是同一行的不同列中。(我对如何将它们拆分为不同的列没有太多想法...)
  2. 我只能添加数字而不是字符串值。因此,如果我写 add_friend(blah, 31, 12, 45),它会返回说 blah未定义。但是,如果我写 add_friend(3,4,5,6),它将把它添加到新行中——但是,只会添加到单个列中。
  3. 该函数的目标是:如果您尝试添加已经在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

1
@Steven,你本可以更新你的另一个问题,那个问题其实就是相同的。把所有问题放在一起更好,这样大家都可以帮助你逐步解决问题。我投票赞成合并。 - Keith Layne
3个回答

5
根据您的要求和您似乎想要做的事情,我写了以下内容。它应该足够详细以便理解。
读取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")

1
  1. 它不会这样做。你为什么认为它会这样做?可能你真正想要的引用方案并不是你指定给csv.writer的那个:即,空格分隔列,而|是引用字符。
  2. blah不是字符串字面量,"blah"才是。没有引号的blah是一个变量引用,在这里该变量不存在。
  3. 为了检查一个名称是否已经在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中。它只会将数字值添加到第一列。还不确定如何处理字符串?感谢您对问题3的帮助!! - Stephen
@Stephen 请尝试以下代码: import csv; from StringIO import StringIO; x = StringIO(); csv.writer(x, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL).writerow(("a", "b", 2, 3)); print x.getvalue() -- 它有四列还是一列?如果你说它有四列,那么我不认为有问题。如果你说它只有一列,那么你选择了错误的列分隔符,因为这是在你选择的列分隔符下有四列,但如果你选择了另一个列分隔符,则只有一列。 - Devin Jeanpierre

0

您没有说明您对Python的经验水平,因此我会把它定得低一些 - 没有冒犯的意思。

  1. 你的作业有几个“要求”。一般来说,你应该确保一个函数只做一件事。因此,为了满足所有要求,你需要多个函数;考虑创建至少一个模块(即,一个包含函数的文件)。

  2. 空格分隔符和 | 用于引号是相当不寻常的。对于当前文件,列之间的分隔符是什么?用于引用/转义文本的是什么?(通过“转义文本”,我指的是:如果我有一个使用逗号作为列分隔符的 csv 文件,并且我想将一个带有逗号的句子放入一个列中,我需要区分表示“新列”的逗号和在列中的句子中的逗号。微软决定 Excel 将支持双引号——因此 "hello, sailor" 成为了一种事实标准。

  3. 如果你想知道 "bob brown” 是否已经在文件中,你需要先读取整个文件,然后再尝试插入。尝试插入之前,你可以使用 'r',然后使用 'w'。但是,每次想要插入一条记录时都要读取整个文件吗?如果你有一百条记录要添加,你应该每次都读取整个文件吗?在添加过程中是否有一种存储名称的方法?

  4. blah 不是一个字符串。它需要加引号才能成为字符串字面量("blah")。blah 只是指一个名为 blah 的变量。如果它说 blah 未定义,那是因为你没有声明变量 blah 来保存任何内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接