一道对10年间中国行政区划个数进行对比的Python考试题

本文起意来自于某 Python 考证班的一道考试题,题目要求使用 import csv 导入模块,对10年间的中国行政区划个数进行对比,编者将采用3种方法进行解题。其中,前2种方法按考题要求使用了  csv 模块功能,并且不可再导入其他模块;第3种方法,作为一种探讨,没有调用 csv 模块,也实现了相关功能。现做如下分享:

数据来源:

从国家统计局官网 https://data.stats.gov.cn/easyquery.htm?cn=C01 查询近10年中国行政区划数据,如下图:

感兴趣读者可以直接打开网页复制相关数据,新建 excel 表格,粘贴并删除第9行以下数据,将【年】替除,另存为【中国行政区划个数.csv】文件,即可运行后边分享的程序。

编程目标:

以2012年为基准数据,能直观查看10年数据变化情况:

1)读取【中国行政区划个数.csv】文件得到原始数据,内容如下图:

2)将2013年至2021所有年份的数值都减去2012年对应的数值;

3)将核减后的新数据存到【中国行政区划个数对比2012年增减情况.csv】新文件中,存储内容如下图:

程序分享:

import csv

filename_in   = './中国行政区划个数.csv'
filename_out1 = './中国行政区划个数对比2012年增减情况_DictReader.csv'
filename_out2 = './中国行政区划个数对比2012年增减情况_reader.csv'
filename_out3 = './中国行政区划个数对比2012年增减情况_str.csv'

#【方法一】
# 调用 csv 模块中 DictReader 类的方法读取 csv 文件的对象,生成数据字典,减值计算修改赋值,
# 最后,调用 csv 模块中 DictWriter 类的方法将字典数据写入指定的文件中

# 步骤一:读取原始数据,形成数据字典 csv_data
with open(filename_in, 'r', encoding='utf-8') as csvfile:
    # DictReader 类用 csv 文件第1行作为字典 key 属性名,并返回一个能遍历 csv 文件
    # 所有行的 csv.DictReader(字典对象) csv_r
    csv_r = csv.DictReader(csvfile)
    csv_data ={} # 初始化 csv 数据字典
    key = 0      # 初始化 csv 数据字典键名
    for row in csv_r: # 遍历 csv 字典对象 csv_r 生成 collections.OrderedDict(采集有序字典) row
        key += 1      # 数值累加生成新键名
        dict ={}      # 初始化【行字典】
        # 利用 items()函数,以列表返回可遍历的(键,值)元组数组
        for k,v in row.items(): # 遍历 collections.OrderedDict 采集有序字典
            if k != '指标':     # 若为非【指标】列,将数值转化为整数赋值 K 键的行字典,用于下一步计算
                dict[k] = int(v)
            else:
                dict[k] = v     # 否则将【指标】列直接赋值 K 键的行字典
        csv_data[key] = dict    # 将【行字典】赋值给 key 键值的 csv_data字典
        # 利用 items()函数,以列表返回可遍历的(键,值)元组数组,计算2013-2021年数量 减2012的差值
        for k,v in csv_data.items():
            v0 = v['2012'] # 将 2012年数量赋值 V0,用于以下2行程序使用
            for y in range(2012,2022):
                v[str(y)] -= v0

# 步骤二:将数据字典 csv_data 按步骤写入指定的文件
fieldname=['指标'] + [str(y) for y in range(2021,2011,-1)] # 利用 for 三元表达式组合生成表头内容
# 以只写模式打开指定的文件,若不存在则新建,若存在则覆盖。为避免空行显示,设置参数:newline=''
with open(filename_out1, 'w', encoding='utf-8',newline='') as f:
    # 调用 csv 模块中类 DictWriter 方法得到 writer 对象
    writer = csv.DictWriter(f,fieldnames=fieldname)
    # 用 writer 对象调用 writeheader() 构造方法,将 fieldnames 参数写入 csv文件第一行或称列标题、表头
    writer.writeheader()
    #调用 writerows() 方法将修改的数据字典的键值写进 csv 文件中
    for k,v in csv_data.items():
        writer.writerow(v)

#【方法二】
# 调用 csv 模块中 reader 类的方法按行读取 csv 文件的迭代对象

# 调用 open() 函数打开指定文件,获取 csvfile 文件对象
csvfile = open(filename_in, 'r', encoding='utf-8')
# 用 csv.reader() 方法传递 csvfile 文件对象参数,创建可遍历的 csv.reader 类型迭代对象
csv_r = csv.reader(csvfile)
n = 0 # 初始化表头判断参数
for row in csv_r: #遍历迭代对象 csv_r, 生成 row 列表数据
    if n == 0: # 为表头第一行,
        # 以只写模式打开指定的文件,若不存在则新建,若存在则覆盖。为避免空行显示,设置参数:newline=''
        with open(filename_out2,'w',encoding='utf-8',newline='') as f:
            # 将 row 行列表数据转换为字符串、替换掉多余字符,行尾加换行符 \n,写入文件
            f.write(str(row).replace("'",'').replace("[",'').replace("]",'')+'\n')
        n = 1 # 完成表头添加后,将判断参数置1
    else:
        m = 0 # 初始化行列表位置参数
        for v in row[::-1]: # 遍历反序行列表,进行差值计算并赋值
            if m == 0 :     # 若 m == 0, 进入计算程序,为下一步计算做准备
                v0 = int(v) # 将2012年字符串数据转换为整数型数据赋值v0,
            m -= 1          # 随遍历将行列表位置参数减1
            if m != -11:    # 如果 m != -11 判断为非【指标】字段,
                row[m] = int(v)-v0 # 执行 int(v)-v0 差值赋值计算
        # 以 'a' 追加模式打开指定的文件
        with open(filename_out2,'a',encoding='utf-8',newline='') as f:
            # 将 row 行列表数据转换为字符串、替换掉'[]多余字符,行尾加换行符 \n,写入文件
            f.write(str(row).replace("'",'').replace("[",'').replace("]",'')+'\n')

#【方法三】
# 不调用 csv 模块,用 file 文件对象 readlines() 函数的方法按行读取 file 文件的迭代对象

# 调用 open() 函数打开指定文件,获取 file 文件对象
file = open(filename_in, 'r', encoding='utf-8')
lines = file.readlines() # 利用 readlines() 按行读取整个文件内容并放到 lines 列表中
n = 0 # 初始化表头判断参数
for row in lines:  #遍历行数据列表
    row = row.replace('\n','') # 去每行数据除行尾的 \n
    if n == 0: # 为表头第一行,
        # 以只写模式打开指定的文件,若不存在则新建,若存在则覆盖。为避免空行显示,设置参数:newline=''
        with open(filename_out3,'w',encoding='utf-8',newline='') as f:
            f.write(str(row)+'\n') # 将 row 第一行数据转换为字符串,行尾加换行符 \n,写入文件
        n = 1 # 完成表头添加后,将判断参数置1
    else:
        m = 0 # 初始化行列表位置参数
        list = row.split(',') # 将字符串型的每行数据转换为行列表数据
        for v in list[::-1]:  # 遍历反序行列表,进行差值计算并赋值
            if m == 0 :       # 若 m == 0, 进入计算程序,为下一步计算做准备
                v0 = int(v)   # 将2012年字符串数据转换为整数型数据赋值v0,
            m -= 1            # 随遍历将行列表位置参数减1
            if m != -11:      # 如果 m != -11 判断为非【指标】字段,
                list[m] = int(v)-v0 # 执行 int(v)-v0 差值赋值计算
        # 以 'a' 追加模式打开指定的文件
        with open(filename_out3,'a',encoding='utf-8',newline='') as f:
            # 将 list 行列表数据转换为字符串、替换掉'[]多余字符,行尾加换行符 \n,写入文件
            f.write(str(list).replace("'",'').replace("[",'').replace("]",'')+'\n')

分享结束,欢迎大家交流想法!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值