Python学习--字典根据值排序并画图

设想这样的一种常见的情境:

我们现在需要统计文本中每个字母出现的频率,最后画出频率的柱状图。为了更加直观的看出字母的频率高低,要求柱状图呈现递减的趋势,即频率高的字母更靠近原点。

容易想到,我们可以用字典存储字母和频率进行计数。

问题的核心在于,根据字典的值,对key进行排序。

直接上代码感受一下,设计的知识点在后面:

import matplotlib.pyplot as plt
text = "a!{ivlotzkEm{CtsvEpbDkwexsotyMuECs!mvlhmenrhwpMh0leydsMbC#CC}sii}tkb}ugCD{zlEeT#kyC0fbukglpopmaekbEthmjcMdsgkvmTnC}eot#dcf{ec@ccgqpfqMycysMuuou!en#{g0cDmoyxTCMgt{joT{jnl0rhoklCe{n0CnxprydeaTg0r{avkEjckjEsxhaohs{Trbkr!ffqip444uwrc}nnevgtCT{jCipogtipzdeDiqsy44rMfj{MzCw#qwg{T4m{cuk!hwuncxdmddeurtsojakrjC#vTDd}0poTT@c!DftjwuDp@mcuheeDtfao!iEcEq}kcf#Mpcam{mml4i4mpDnedamcwtC0nem{mDotnmp4jf@TpxfqMoiqwtdijDfimmCzmxe#gsTu{poeTEhD!u0anvTTTbbi{q}zapcksMifDlovoeac@{0keh0dg{Mi!@tfftqitmuMoMcuTpmcgnmozyrrv#zfmzmetyxxa0wczE}eoD{xcMnoCuebu0otdusiDknfvo0{fEsMftzT!eoslegbypspC4vkxm#uaf@acuemhMyiDou#at0rfl4a}0ixeEktws}pMCfCigaTafg}ffssmwwuTkTuls0{M@c4e@{D{tuorzmyqptChpngkeCohCCMTwqctinc0mcjemclv@cMoqf00poarte@oqmuysm#mo{et4kcCpcgcT}vD}m!g4{E0!Mol0fpo!{srT0pf{cMuCx0bp{ftTmExcrn}0etonez!@C4tfa4aM00siztb@fomfD#{#tMbo@jgb4CM0dEk0tea4aMCafn"

# 创建一个空字典来存储字母计数
letter_counts = {}

# 遍历文本中的每个字符
for char in text:
    # 仅考虑字母字符
    if char.isalpha():
        # 将字母转换为小写
        char = char.lower()
        # 如果字母已经在字典中,则增加计数
        if char in letter_counts:
            letter_counts[char] += 1
        # 如果字母不在字典中,则将其添加并设置计数为1
        else:
            letter_counts[char] = 1
            
# 按频率排序字典,频率高的在前
sorted_counts = sorted(letter_counts.items(), key=lambda item: item[1], reverse=True)
letters, frequencies = zip(*sorted_counts)

# 绘制柱形图
plt.bar(letters, frequencies)
plt.xlabel('Letters')
plt.ylabel('Frequency')
plt.title('Frequency of Each Letter (Highest on the Left)')
plt.tight_layout()  # 调整布局以防止标签重叠
plt.show()

*解构运算

在Python中,* 运算符有多种用法,其中之一是用于解压可迭代对象。当 * 运算符与可迭代对象一起使用时,它可以将可迭代对象中的元素解压并作为单独的参数传递给函数或构造新的数据结构。

让我们来看一些示例来详细解释 * 运算符的用法:

解压可迭代对象

# 解压元组
values = (1, 2, 3)
print(*values)  # 打印结果为 1 2 3

# 解压列表
my_list = [4, 5, 6]
print(*my_list)  # 打印结果为 4 5 6

传递可变数量的参数给函数

# 定义一个函数,接受三个参数
def my_function(a, b, c):
    print(a, b, c)

# 使用 * 运算符传递参数
my_values = (1, 2, 3)
my_function(*my_values)  # 等同于 my_function(1, 2, 3)

解压字典键值对

# 解压字典的键值对
my_dict = {'a': 1, 'b': 2, 'c': 3}
print(*my_dict)  # 打印结果为 a b c,仅打印了字典的键
print(*my_dict.items())  # 打印结果为 ('a', 1) ('b', 2) ('c', 3),打印了键值对元组

在代码 letters, frequencies = zip(*sorted_counts) 中,*sorted_counts 就是使用 * 运算符来解压 sorted_counts 列表中的元组。

zip函数

zip 函数是一个内置函数,用于将多个可迭代对象(如列表、元组等)中对应位置的元素打包成一个元组,并返回这些元组组成的迭代器。这使得可以同时迭代多个可迭代对象,将它们的元素一一对应起来。

下面是 zip 函数的基本用法和示例:

基本语法

zip(iterable1, iterable2, ...)

示例

# 创建两个列表
letters = ['a', 'b', 'c']
numbers = [1, 2, 3]

# 使用 zip 函数打包两个列表中对应位置的元素
zipped = zip(letters, numbers)

# 打印结果
for item in zipped:
    print(item)

输出

('a', 1)
('b', 2)
('c', 3)

在示例中,zip(letters, numbers) 将 letters 列表和 numbers 列表中对应位置的元素打包成元组,然后返回一个迭代器。在 for 循环中,我们遍历这个迭代器并打印每个元组,每个元组包含了两个列表对应位置的元素。

值得注意的是,如果传递给 zip 函数的可迭代对象长度不一致,zip 函数会以最短的可迭代对象的长度为准,多出来的部分会被忽略。

zip 函数在处理多个可迭代对象时非常有用,特别是在需要同时处理多个列表或元组的情况下。

letters, frequencies = zip(*sorted_counts)
这行代码就是先把sorted_counts拆成很多个元组,然后zip可以将每个元组相同位置的元素,打包成一个新的元组。

#*sorted_count
('m', 66) ('c', 65) ('t', 60) ('e', 52) ('o', 37) ('d', 33) ('f', 33) ('p', 28) ('u', 27) ('a', 25) ('s', 24) ('k', 23) ('i', 22) ('n', 21) ('g', 20) ('r', 17) ('v', 14) ('l', 14) ('z', 14) ('b', 14) ('w', 14) ('x', 14) ('y', 14) ('h', 14) ('j', 14) ('q', 14)

zip(*sorted_count)
(
('m', 'c', 't', 'e', 'o', 'd', 'f', 'p', 'u', 'a', 's', 'k', 'i', 'n', 'g', 'r', 'v', 'l', 'z', 'b', 'w', 'x', 'y', 'h', 'j', 'q'),
(66, 65, 60, 52, 37, 33, 33, 28, 27, 25, 24, 23, 22, 21, 20, 17, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14)
)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值