讨论/综合讨论/Python的答案验证也开始检查类型了吗?/
Python的答案验证也开始检查类型了吗?

以前返回迭代器或生成器也能通过的题目现在需要返回列表了,以前返回None也可以通过False的题目,现在必须返回bool相关类型了。

对于Python来说,这样更好吗?

展开讨论
共 3 个讨论

我觉得类型检查没有问题,既然函数已经声明了是什么类型,就应该按照对应的类型返回,要不然声明的类型还有什么用呢?连 mypy 都过不了。如果要返回包含 Nonebool ,那么就应该声明 Optional[bool];如果要返回生成器,那么就应该声明 Iterable

以前自己写就因为这种情况吃亏:
函数声明返回的是 List ,但是却返回了生成器,而外部有两处使用的地方,导致第一次遍历没有问题,第二次就没有可遍历的元素。
这种情况我单步调试才找出来,如果看代码,还需要进去函数内部看,甚至很快就会忘记两者的关联。既然函数已经抽出去了,那么就应该是保证声明类型和真实类型一致,管好自己的函数。
如果有道题入参声明是 List ,让你反转之后再返回,你相信传入的就是 List ,直接在原有数组上进行操作,这时候传入了迭代器不就炸了。既然你相信了入参的类型,那么也应该保证返回的类型也一致。函数签名是和他人交流的桥梁,不是每个人都有时间进入函数内部看返回的真实类型的。

4

主要是俺写的题解的和评论,
保守估计一半是列表返回迭代器或者返回值为False时不写返回值的,
几百个有问题的互动将会被质疑,
也太坑了,早检查类型也就没这回事了。

不过也是因为在leetcode用惯了迭代器作为返回值,
才发现Python的世界还真就是迭代器的世界,
迭代器真是伟大的语言发明。
也理解了Python随着版本更新,
为什么越来越多的内置库函数都改成以迭代器作为函数返回值的趋势。

我现在的日常代码已经变得能yieldyield了,
省内存,速度快,代码也更简洁,
测试过比声明一个列表作为返回变量要快15-30%这样。
真想拿列表就是直接list(generator())或者[*generator()]就完事了,
但绝大多数情况下转列表完全多余,循环迭代输出就够用了。

leetcode的验证程序估计要兼容不同语言,
都是去迭代可迭代对象进行脏检查的,
绝大多数情况返回迭代器还能节省服务器资源。

在手机上简单撸了一个时间验证程序,生成器核心代码永远比数组法少两行,而且迭代效率要高于数组生成。

image.png

image.png

同时bool类型判断也挺多余的。
大多数真值判断式都是if truth(): ...作为判断的,
若写成if truth() == True: ...
或者if truth() is True: ...
代码既罗嗦又低效,
测试过大约会慢20-30%这样,
当然,亲测最快的还是truth() and ...

其次,我之前也测过同样是bool(T) == False的,None, False, 0, .0, '', (), [], set(), {}None的内存最小,也最快。
所以返回None作为真值判断也是很优先的选择。

最后,旗帜鲜明的反对Python返回值的类型验证。

类型系统在目前已经成为各个社区的政治正确了,尤其是JavaScript这两年向TypeScript的迁移,作为弱类型语言,js确实在很多时候很坑,转ts问题不大。

但在Python这边,其实并不太适用,Python不同可迭代类型的交互大概率直接报错,而且报错定位也精准,比js的情况要好得多。
再说,过于复杂项目目前一般不太可能用Python,中小项目加上类型系统大概率是心智负担,不过作为提示是没问题。

作为web后端语言,寻求类型系统不如去做Java/Golang,作为数据处理语言,numpy等库的类型系统已经够用,额外的类型检验系统基本就是多余,想搞纯类型,不如用Cython或者声明列表的时候用内置库可以限制类型的array库,不过提前说好,array类型的整体效率要比原生list类型慢30-40%。

说的有点偏了,其实类型系统本身没啥错,重点还是在输出是数组比较好还是迭代器比较好,以及bool类型是否需要类型校验上。

比起返回都是数组,其实宁愿返回都是迭代器。

2

python 还真的是 能用迭代器就用迭代器。快,而且简洁… 除非是类似数值0判断,None False 0 空 应该是等价对待的。 bool型的,检查下类型可以,列表型之类没必要了。

1