Python技术迷

字节校招生:每天仅洗数据,年薪自爆 180万…

刚看到个贴子,说有字节校招生自曝年薪总包 180 万,每天主要工作就是“洗数据”,还连收两笔期权,语气里那叫一个得意:去阿里美团现在估计肠子都悔青了。

Image

网友回帖一半羡慕一半酸,但我看了看,核心就是——价值够高,行情自然不差。大厂给的钱从来不是慈善,能给到这个级别,要么项目在风口,要么人家真的能创造价值。

别看他说“洗数据”轻松,真干过的都知道,洗不好直接影响业务,背后的压力也不小。

网友有人说这属于“爽到别人头上了”,校招生赶上好机会,本身能力也匹配,既运气又实力,没啥可酸的。

换个角度想,普通人不必因为别人年薪 180 万就怀疑人生,每个人赛道不同,机会也不同。说到底,职场就是交换价值,能被需要就能拿高薪。【备注:文末可领最新资料】

面试题:统计各专业学生人数

平时写后台的时候,经常会碰到这种小需求:教务系统导出了一堆学生数据,现在领导一句话——“按专业统计下有多少人”,看着上千行 Excel,总不能手工数吧,那这就是典型的“统计各专业学生人数”的算法题了。

我们可以先把题目抽象一下,不管你数据是从数据库查出来的,还是从接口拿到的,本质上就是一堆“学生记录”,每条记录里有个字段代表专业,比如:

students = [
    {"name": "张三", "major": "计算机"},
    {"name": "李四", "major": "金融"},
    {"name": "王五", "major": "计算机"},
]

我们要做的,就是把这堆学生扫一遍,最后得到一个结果:

{
"计算机": 2,
"金融": 1
}

说白了,就是“按专业分组,然后每组里的人头数一下”。

最直接、也是最实用的做法:字典计数

这个需求其实不用想太复杂,最自然的想法就是:我弄一个空的“统计表”,每看到一个学生,就在表里把他那个专业的数字加一。

在 Python 里,这个“统计表”用字典最合适,键是专业名,值是人数。伪流程是这样的:

  1. 准备一个空字典 major_count = {}
  2. 遍历每个学生
  3. 取出他的 major
  4. 如果这个专业之前没见过,就先放进去,人数设成 0
  5. 然后这个专业人数加一

写成 Python 就长这样:

defcount_students_by_major(students):
    major_count = {}

for stu in students:
        major = stu.get("major")
ifnot major:  # 万一有缺失数据,简单跳过
continue

if major notin major_count:
            major_count[major] = 0

        major_count[major] += 1

return major_count


if __name__ == "__main__":
    students = [
        {"name": "张三", "major": "计算机"},
        {"name": "李四", "major": "金融"},
        {"name": "王五", "major": "计算机"},
        {"name": "赵六", "major": "数学"},
    ]

    result = count_students_by_major(students)
    print(result)  # {'计算机': 2, '金融': 1, '数学': 1}

这个算法的时间复杂度就是 O(n),n 是学生人数,因为就是老老实实扫一遍;空间复杂度大概是“有多少不同的专业就占多少格”,O(k),k 是专业种类数。对实际业务来说,已经足够高效了。

换个输入方式:从控制台读、从文件读

上面是最直观的“内存里已经有对象”的写法。算法题里更常见的是:输入第一行是学生数量,后面每行一个“姓名 专业”,最后输出每个专业的人数。

比如输入是:

5
张三 计算机
李四 金融
王五 计算机
赵六 数学
小明 金融

我们可以这么写:

defmain():
    n = int(input().strip())
    major_count = {}

for _ in range(n):
        line = input().strip()
ifnot line:
continue
        parts = line.split()
# 假设格式固定为:姓名 专业
if len(parts) < 2:
continue
        name, major = parts[0], parts[1]

        major_count[major] = major_count.get(major, 0) + 1

# 输出时按专业名字排序一下,看着更整齐
for major in sorted(major_count.keys()):
        print(major, major_count[major])


if __name__ == "__main__":
    main()

这里多用了一个小技巧:dict.get(key, default),这样就不用先判断 key 在不在字典里,写起来更顺。

如果你是在实际项目里干这个事情,学生信息可能在 CSV 文件里,那读文件的版本差不多,也是那套思路:

import csv

defcount_from_csv(path):
    major_count = {}
with open(path, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
for row in reader:
            major = row.get("major")
ifnot major:
continue
            major_count[major] = major_count.get(major, 0) + 1
return major_count

可以看到,输入从哪来不重要,核心逻辑就那几行字典计数。

再顺带提一下 collections.Counter

如果想写得更“Pythonic”一点,还可以用标准库里的 collections.Counter,专门就是干计数这活的:

from collections import Counter

defcount_students_by_major(students):
    majors = [stu.get("major") for stu in students if stu.get("major")]
return Counter(majors)

最后返回的 Counter 跟字典类似,用起来也差不多。

整体来说,这个“统计各专业学生人数”的题,其实就是“按某个字段分组计数”的通用套路:扫一遍,用字典累加。以后不管是按城市统计用户数、按商品统计销量、按日期统计访问量,都是同一个模式,熟练掌握这一种思路,很多业务需求一眼就能写出来了。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB