众数
老码农:小码匠,我向你保证,今天的算法一点也不难。
小码匠:不难?我信你个鬼,你给我整的题有不难的?算了,说来听听吧。
老码农:来来来,上菜,本期的菜——求众数
-
输入:列表中有多个数据。
-
输出:求这个数据列表中,出现次数最多的数据。
-
百度百科
https://baike.baidu.com/item/%E4%BC%97%E6%95%B0/44796?fr=aladdin
小码匠:唔,我明白了,这个看起来的确不难,用一句你们“码农”界的行话,“开撸代码”,走起。
老码农:学的够快的哈,那就赶紧做吧。
小码匠:唔,这里这样,不对应该这样……
小码匠一阵噼里啪啦,呈现如下代码:
def mode(input_list: list) -> list:
"""
众数
href: https://baike.baidu.com/item/%E4%BC%97%E6%95%B0/44796
input_list: list[int] 数值型数据列表
returns: float: 众数列表
"""
if not input_list:
raise ValueError("你输入的是个空列表")
input_set = list(set(input_list))
dic = dict()
li = []
for i in input_set:
dic[i] = input_list.count(i)
num = max(list(dic.values()))
for j in dic.keys():
if dic[j] == num:
li.append(j)
if __name__ == "__main__":
# print(mode([]))
print(mode([60]))
print(mode([60, 60]))
print(mode([10, 10, 20, 30, 40, 10, 70, 80, 90]))
print(mode([60, 10, 20, 10, 40, 50, 70, 50, 90]))
老码农:先运行,看结果对吗?
小码匠轻点运行按钮
小码匠:哎,什么情况,怎么输出的都是None?
/System/Volumes/Data/fgb/01.git/04.coder/04.coding/coder-algorithm/venv/bin/python /System/Volumes/Data/fgb/01.git/04.coder/04.coding/coder-algorithm/algorithm/maths/mode.py
None
None
None
None
Process finished with exit code 0
老码农在一旁窃笑:啧啧啧,小码匠,不行啊。
小码匠:一边去,别妨碍我。
小码匠盯着屏幕,先看看代码再说:“😺哎呀,原来我忘了写返回值了。”
小码匠飞速的加了几个字符,再run。
return li
结果:
[60]
[60]
[10]
[10, 50]
Process finished with exit code 0
老码农:结果是对的,再考你个小知识点,这块能换个写法吗?
num = max(list(dic.values()))
for j in dic.keys():
if dic[j] == num:
li.append(j)
return li
小码匠:你是说循环用key,value吗?和这个不一样吗?没必要再写吧。
老码农:你就试试吧,我就想检查你的基本功是否扎实。
(步步为营,你的基础知识不扎实是不可以能的,老码农,心机有些深!😊)
小码匠:嗯,这个不难,你稍等会儿。
num = max(list(dic.values()))
for key, value in dic.items():
if num == value:
li.append(key)
# for j in dic.keys():
# if dic[j] == num:
# li.append(j)
return li
老码农:你为什么不把刚才写的删掉啊,还留着它没用啊。
小码匠:这也是我辛辛苦苦敲的,留着吧。
老码农坚决的说:不,你必须删掉。我要对你负责。
小码匠:这,留着也没什么吧。
老码农:**《代码整洁之道》**的书看完了吗?
小码匠:还没看呢。我哪有时间啊,每天你一到家,就被你抓了壮丁,让我写代码,最近看书的时间都严重被你压缩。
老码农:先删掉吧,看完那本书,你就明白我为啥要让你删掉了。
小码匠不情愿的动了几下手指……
老码农:numpy看完了吧。这个用numpy应该也可以实现的,我记得有内置函数的。
小码匠:我记得numpy没提供内置函数啊。
老码农:应该有吧,我试试。
import numpy as np
def mode_numpy(input_list: list) -> list:
return np.....
老码农敲入np.xxx,悲剧,没提供内置函数。
小码匠:哈哈哈哈哈,看你,毫不意外的翻车了。
老码农:看你开心的,老爸上了年纪了,记忆是有些退化了。
小码匠:不要为自己找借口,好歹也当码农当了这么多年。
老码农:你尝试pandas吧,pandas肯定有,这个我用过。
小码匠:这个嘛,好像是有的,我刚学过。我来编吧。
import pandas as pd
def mode_pandas(input_list: list) -> list:
return pd.Series(input_list).mode().to_list()
if __name__ == "__main__":
# print(mode([]))
print(mode_pandas([60]))
print(mode_pandas([60, 60]))
print(mode_pandas([10, 10, 20, 30, 40, 10, 70, 80, 90]))
print(mode_pandas([60, 10, 20, 10, 40, 50, 70, 50, 90]))
老码农:先run,看看结果。
小码匠又一次按下运行按钮,结果呈现如下:
[60]
[60]
[10]
[10, 50]
Process finished with exit code 0
老码农:不错,不错,把那个循环再优化下吧,就这里。
for key, value in dic.items():
if num == value:
li.append(key)
小码匠:推导式呗。
老码农:你的那个变量命名我看着不太舒服,那个改成
li -> count_dict
小码匠:严重洁癖,我改。
小码匠又是几声噼里啪啦。代码呈现如下
import pandas as pd
def mode(input_list: list) -> list:
"""
众数
href: https://baike.baidu.com/item/%E4%BC%97%E6%95%B0/44796
input_list: list[int] 数值型数据列表
returns: 众数列表
"""
if not input_list:
raise ValueError("你输入的是个空列表")
input_set_list = list(set(input_list))
count_dict = dict()
for value in input_set_list:
count_dict[value] = input_list.count(value)
num = max(list(count_dict.values()))
return [key for key, value in count_dict.items() if num == value]
def mode_pandas(input_list: list) -> list:
return pd.Series(input_list).mode().to_list()
if __name__ == "__main__":
# print(mode([]))
print(mode([60]))
print(mode([60, 60]))
print(mode([10, 10, 20, 30, 40, 10, 70, 80, 90]))
print(mode([60, 10, 20, 10, 40, 50, 70, 50, 90]))
老码农:perfect
向大神致敬
老码农:小码匠,写的不错。咱们去同行那取取经,看看人家是怎么写程序的。
小码匠:你的这个工程是哪来的?让我看看呗。
老码农:你先别看人家代码了,咱们做对比学习,取长补短。我能告诉你的是,这个库是几个印度小哥搞的,包括各种Python算法,github标星118K,很🔥的。
啥时候,咱们国人也搞几个火的一塌糊涂的该多好啊。老码匠一生长叹。
老码农:你先看看这段代码吧。从中能学到什么知识。
def mode(input_list: list) -> list: # Defining function "mode."
"""This function returns the mode(Mode as in the measures of
central tendency) of the input data.
The input list may contain any Datastructure or any Datatype.
>>> input_list = [2, 3, 4, 5, 3, 4, 2, 5, 2, 2, 4, 2, 2, 2]
>>> mode(input_list)
[2]
>>> input_list = [3, 4, 5, 3, 4, 2, 5, 2, 2, 4, 4, 2, 2, 2]
>>> mode(input_list)
[2]
>>> input_list = [3, 4, 5, 3, 4, 2, 5, 2, 2, 4, 4, 4, 2, 2, 4, 2]
>>> mode(input_list)
[2, 4]
>>> input_list = ["x", "y", "y", "z"]
>>> mode(input_list)
['y']
>>> input_list = ["x", "x" , "y", "y", "z"]
>>> mode(input_list)
['x', 'y']
"""
result = list() # Empty list to store the counts of elements in input_list
for x in input_list:
result.append(input_list.count(x))
if not result:
return []
y = max(result) # Gets the maximum value in the result list.
# Gets values of modes
result = {input_list[i] for i, value in enumerate(result) if value == y}
return sorted(result)
if __name__ == "__main__":
import doctest
doctest.testmod()
小码匠:嗯,我就喜欢跟高手学习。小码匠仔细看起代码。
小码匠:老码农老码农,你快过来看看。我感觉这个有些地方编的不太好。
老码农:是吗?你说。
小码匠:我觉得……
-
先去重再循环,我觉得会更好,代码对比
input_set_list = list(set(input_list)) count_dict = dict() for value in input_set_list: count_dict[value] = input_list.count(value) num = max(list(count_dict.values()))
result = list() # Empty list to store the counts of elements in input_list for x in input_list: result.append(input_list.count(x))
-
第二点呢
-
-
我的:判空放上面,空直接抛出了异常。
if not input_list: raise ValueError("你输入的是个空列表")
-
他的:先统计各个字符数量,然后再判空。我觉的不太合理,先判空更合理些。
if not result: return []
-
-
第三点呢,这块我没太懂,他排序干嘛啊?
return sorted(result)
老码农:嗯,你说的有道理。
- 第一点,二点我认可。
- 第三点,他是对众数结果列表排了序,默认应该是升序的方式,看结果会更方便吧。
小码匠:这点挺好的,收了。还有第二点,我觉得返回空会更合理,只是先判断就更好了,这点我也收了。
老码农:还有其他你需要学习的地方吗?
小码匠:应该没了。
老码农:👌我认为这块印度小哥做的特别好。需要咱们俩去学习。
- 注释这块,测试Case这块考虑的比较全。我们要学习
编写程序一定要考虑周全,一旦出现大BUG,就悲剧了,少则损失几十万,大则几千万,团队解散都有可能。
This function returns the mode(Mode as in the measures of
central tendency) of the input data.
The input list may contain any Datastructure or any Datatype.
>>> input_list = [3, 4, 5, 3, 4, 2, 5, 2, 2, 4, 4, 4, 2, 2, 4, 2]
>>> mode(input_list)
[2, 4]
>>> input_list = ["x", "y", "y", "z"]
>>> mode(input_list)
['y']
>>> input_list = ["x", "x" , "y", "y", "z"]
>>> mode(input_list)
['x', 'y']
小码匠:你说的我有些不太懂,一个BUG会损失那么大吗?
老码匠:会,很严重的。一定要重视,所以平时你写代码我都要求比较严的。严格是对小码匠负责,更是对你未来负责的。体会到老爸的良苦用心了吧。
小码匠:嗯,明白了。谢谢老爸,我会好好写代码哒!
思索
*教育的实质应该是什么样子呢?*
**是要培养孩子的质疑精神,多问问题的精神,**而不是培养成程式化的机器人。
**国外的家长回家问孩子,总是问,今天你提问了吗?**提了几个问题?
**国内家长问的都是,今天考试了吗?****考了多少分?**排第几?
这就是教育理念的差别。
这种艰深命题,需要家长和娃娃一起改变,一起学习,打破旧的思维模式。
从现在开始,从娃娃抓起,从教育入手,培养孩们好奇心和创造力的创新思维。