使用字典和列表型变量完成村长选举。某村有40名有选举权和被选举权的村民,名单在附件name.txt中,从这40名村民中选出一人当村长,40人的投票信息由附件vote.txt中给出,每行是一张选票的信息,有效票中得票最多的村民当选。
问题1:请从vote.txt 中筛选出无效票写入文件vote1.txt 。有效票的含义是:选票中只有一个名字且该名字在name.txt文件列表中,不是有效票的票称之为无效票。
f = open("name.txt","r",encoding="utf-8")
names = f.readlines() #从文件中读入所有行,以每行元素形成一个列表
f.close()
f = open("vote.txt","r",encoding="utf-8")
votes = f.readlines()
f.close()
D = {} #生成空字典
NUM = 0 #统计有效投票
for vote in votes:
num = len(vote.split()) #分解成列表,并求列表长度(元素个数)。str.split(sep=None):返回一个列表,由str根据sep被分割的部分构成,省略sep默认以空格分割。num为1或2
if num == 1 and vote in names: # 仅一个且在姓名中,有效
D[vote[:-1]] = D.get(vote[:-1], 0) + 1 #此时已经确定该行vote有效即只有一个人名,现要统计这行vote(人名)对应的票数。vote是一个字符串(由人名+换行符组成),vote[N:M]表示字符串中从N到M(不包含M)的子字符串,如果M或N缺失,则默认把开始或者结束作为索引值。所以vote[:-1]表示去掉vote这个字符串的最后一个字符,也就是换行符。D.get(vote[:-1],0)这个是字典的使用,d.get(k,<default>):键k存在,则返回相应值,不存在则返回 <default>值。在D字典中找vote[:-1]即某一人名,没有的话给这个键的值赋0,有的话+1,完成按有效投票计数操作。D是一个字典,D[键]会输出键对应的值。
NUM += 1
else:
with open("vote1.txt", "a+", encoding="utf-8") as fi:# 文件的常规读写方式是open()...close(),这样如果读取过程中出现异常,在执行open操作之后将无法close即文件无法关闭。而with open as方法到达语句末尾时,会自动关闭文件,即便出现异常。a+表示 追加写模式+读文件,如果只是a,可以向文件中写信息,但是不能从文件中读信息。
fi.write(vote) # 如果无效即一张票上有两个人名,保存到vote1文件内
问题2:给出当选村长的名字及其得票数。
f = open("name.txt","r",encoding="utf-8")
names = f.readlines()
f.close()
f = open("vote.txt","r",encoding="utf-8")
votes = f.readlines()
f.close()
D = {}
NUM = 0
for vote in votes:
num = len(vote.split()) # 分解成列表,并求列表长度(元素个数)
if num == 1 and vote in names: # 仅一个且在姓名中,有效
D[vote[:-1]] = D.get(vote[:-1], 0)+1
NUM += 1
l = list(D.items()) #D是一个字典,键为人名,值为对应的票数。<d>.items()返回所有的键值对,list()函数将返回值转换成列表
l.sort(key=lambda s: s[1], reverse=True) #sort方法中的lambda用来指定在列表中使用哪一列作为排序列。默认的排序方法是从小到大,若reverse=True,则返回的排序就是从大到小。这行代码的功能就是对一个列表按照键值对的2个元素的第2个元素进行排序。
name = l[0][0]
score = l[0][1]
print("有效票数为:{} 当选村民为:{},票数为:{}".format(NUM, name, score))