Python技术迷

除了少数核心人员其余年龄超过35岁的人全部被裁员了~

刚看到个贴子,说一位38岁的程序员面试时提到,公司业务线除了少数核心人员,其余35岁以上的全被裁了😮。

Image

作为程序员,这事儿真不新鲜,技术圈就是这样,年龄和“性价比”总被直接挂钩。网友有说不公平的,也有人感叹时代残酷。 我觉得关键在于,技术人的价值不能只押在“能写代码”上。35+被裁,不只是年龄问题,而是公司觉得你成本高、替代性强。

核心人员能留下,是因为他们的价值是不可替代的,比如对业务的深度理解、跨团队协调能力,或者能在关键时刻扛住全局。 换句话说,职场像游戏副本,你不能永远只靠同一招吃饭。学新技术、懂业务、会带人,才是保命技能。代码会老,思维要常新。 技术人最好的安全感,是不断提升自己在团队的不可替代性💪。【备注:文末可领最新资料】

面试题:统计重复个数

昨天晚上十一点多,在公司楼下抽烟…不是,我不抽烟,陪我们组那个小李吹风,他突然问我:“哥,那个统计重复个数…怎么写来着?”我一愣,就是那个…怎么说呢…就是给你一堆东西,找出谁重复了、各自重复几次,对吧。行,我困得眼冒金星,但这活儿好上手。

输入可能是列表、字符串,甚至一行一行从文件里读。目标很朴素:把每个元素出现次数数出来,然后你要嘛返回一张“频次表”,要嘛只挑出重复的那些(次数>1)。注意点是大小写、空白、以及None、NaN这类“怪东西”,别被坑了。还有,数据特别大时,内存会顶不住,得边读边数。

说白了呀,思路就俩字:计数。最顺手的是哈希(字典)统计;偷懒就用collections.Counter;数据太大或者顺序不重要,也可以先排序再扫一遍。复杂度心里有数:哈希是O(n)均摊,排序是O(n log n),但省一点点内存跳转。

from collections import Counter
from math import isnan

defnormalize(x, *, case_insensitive=False, strip_ws=False):
# 小清洗:大小写、空白、NaN统一一下,避免“看着一样其实不一样”
if isinstance(x, float):
try:
if isnan(x):
return"NaN"
except Exception:
pass
if isinstance(x, str):
if strip_ws:
            x = x.strip()
if case_insensitive:
            x = x.lower()
return x

defcount_freq(iterable, *, case_insensitive=False, strip_ws=False, only_dups=False):
    freq = Counter()
for item in iterable:
        key = normalize(item, case_insensitive=case_insensitive, strip_ws=strip_ws)
        freq[key] += 1
return {k: c for k, c in freq.items() if (c > 1if only_dups elseTrue)}

# 示例1:列表里的重复元素
data = ["A", "b", "a", "B", "b ", None, "", " ", "a"]
print(count_freq(data, case_insensitive=True, strip_ws=True))      # 全部频次
print(count_freq(data, case_insensitive=True, strip_ws=True, only_dups=True))  # 只要重复的

# 示例2:字符串里重复字符
s = "mississippi"
print(count_freq(s, only_dups=True))  # {'i': 4, 's': 4, 'p': 2}

# 示例3:从大文件中按“词”统计(流式,不爆内存)
defwords_from_file(path):
with open(path, "r", encoding="utf-8", errors="ignore") as f:
for line in f:
# 简单分词,标点清洗你们自己看情况加
for w in line.strip().split():
yield w

# freq_map = count_freq(words_from_file("big.txt"), case_insensitive=True, strip_ws=True)
# dups_only = {w: c for w, c in freq_map.items() if c > 1}

有人问我,那个API…哦对是Counter,是不是永远最快?不绝对。小数据差不多;极端大数据时,自己维护dict和复用对象能省点常数,还能嵌自定义清洗逻辑。还有排序法也香:如果你能接受改顺序,sorted(data)后,线性扫一遍就行,空间占用更稳一点:

defcount_by_sort(iterable):
    it = iter(sorted(iterable))
try:
        prev = next(it)
except StopIteration:
return {}
    ans, run, cnt = {}, prev, 1
for x in it:
if x == run:
            cnt += 1
else:
            ans[run] = cnt
            run, cnt = x, 1
    ans[run] = cnt
return ans

就是那个…大小写要不要统一?“A”和“a”算一样吗;字符串两边的空白要不要strip;空字符串""和一个空格" "别混为一谈;还有None、NaN要不要单独归类。要做“去重之后再数”这种骚操作就别瞎搞,顺序是“先清洗再统计”,不然统计口径乱了,结果会飘。哦对了,中文分词别用split()顶上,场景复杂点就上分词器,这里我就不展开,太困了。

哈希统计:时间O(n)、空间O(k)(k是不同元素个数),大多数业务够了;排序统计:O(n log n)时间、近似O(1)额外空间(忽略排序实现细节),在内存紧张时挺稳。交付时一般给两份结果:一份完整频次表,一份只含重复的项;再排序一下方便看,比如按次数降序:

deftop_duplicates(freq_map, min_count=2, top_k=None):
    items = [(k, c) for k, c in freq_map.items() if c >= min_count]
    items.sort(key=lambda x: (-x[1], str(x[0])))
return items[:top_k] if top_k else items

行吧,我回家了…对了,有人问“为什么我统计出来的空格那么多?”八成是日志里混了制表符和全角空格,先统一再数,别问我怎么知道的,唉。

-END-

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

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领