GitHub标星12.1W,印度小哥代码在质疑中学习

众数

老码农:今天的算法也不难。

小码匠:快说题目。

老码农:上菜,本期的菜:求众数

小码匠:明白,用你们码农界的行话,那我开撸代码了啊。

老码农:学的够快的。

小码匠一阵噼里啪啦,呈现如下代码:

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

老码农:你为什么不把刚才写的删掉啊,还留着他没用啊。

小码匠:我辛辛苦苦敲的,留着吧。

老码农坚决的说:不,你必须删掉。我要对你负责。

小码匠:留着也没什么吧。

老码农:《代码整洁之道》的书看完了吗?

img

小码匠:还没看呢。我哪有时间啊,每天你一到家,就抓壮丁,让我写代码,最近看书的时间严重被你压缩。

老码农:先删掉吧,看完那本书,你就明白我为啥要让你删掉了。

小码匠不情愿的动了几下手指。。。

老码农: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标星121K,很🔥的。

啥时候,咱们国内也搞几个火的一塌糊涂的该多好啊。老码匠一生长叹。

老码农:你先看看这段代码吧。从中能学到什么知识。

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会损失那么大吗?

老码匠:会,很严重的。一定要重视,所以平时你写代码我都要求比较严的。严格是对小码匠负责,更是对你未来负责的体会到老爸的良苦用心了吧。

小码匠:嗯,明白了。谢谢老爸,我会好好写代码的。

感悟

教育的实质应该是什么样子呢?

是要培养孩子的质疑精神,多问问题的精神,

而不是培养成程式化的机器人。

国外的家长回家问孩子,总是问,今天你提问了吗?

提了几个问题,而我们国内家长问的都是,今天考试了吗?

考了多少分?

排第几。

这就是教育的差别。

“为什么我们的学校总是培养不出杰出人才?”这就是著名的“钱学森之问”。

纵观IT领域,我们使用的编程语言,开发框架,各种开发工具,数据库等都是老外搞的,

我们更多的是在复制,缺乏创新。

从现在开始,从娃娃抓起,从教育入手,培养孩们好奇心和创造力的创新思维。

为什么刷算法

为啥刷算法?

不知道!

为啥不知道?

老码农让我干的!

为啥老码农让你刷?

我哪知道啊!

为啥不知道?

老码农让我干的!

悲剧,死循环…

img

关注公众号【小码匠和老码农】收获小码匠和老码农精心挑选的电子书

  • 回复【算法】收获算法书电子书

  • 回复【python】收获python基础电子书

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值