Python 为什么用 len() 函数,不用 x.len() 风格?

文章探讨了Python使用内置函数len()而不是对象方法x.len()的原因,包括速度、可读性和设计哲学。Python的len()是直接从C结构体读取长度,提高效率;前缀表达式更符合数学传统,增强可读性。此外,文章还讨论了Python内置函数的独立性以及list.sort()不返回新列表的性能考虑。
摘要由CSDN通过智能技术生成

原文参考: https://github.com/chinesehuazhou/python-whydo/blob/master/zh_CN/1-why-design-len()-and-not-x.len().md

为什么python求长度使用len作为内置函数,其他语言使用x.length()写法

主要有3个原因:
一. 将len设置为内置函数,可以直接读取底层的C结构体,速度快

Python 之禅: “实用胜于纯粹”
CPython会直接从C结构体读取对象长度,不会调用任何方法,而且获取长度是一个常见操作,如str,list,memoryview等类型上,操作必须高效, abs同理
Python 之禅:“不能让特例特殊到开始破坏既定规则。”

二. 前缀可读性更高,简单胜过复杂

三. 见名知意, len(x) 就是求长度的
作为新手友好型语言,内置方法起了很大作用

在python中:

str = "Hello World!"
print(len(str))

在Java中

String str = "Hello World!";
System.out.println(str.length());

Python 采用的是一种前缀表达式 ,而 Java 采用的则是后缀表达式 。

其他内置函数

int(s)
str(i)

类似于java的

Integer.parseInt(s);
String.valueOf(i);

Python 的内置函数不与特定的类绑定,它们是一级对象。而 Java 的“函数”则无法脱离类而存在,它们只是附属品。
没有绝对的好坏
python也有后缀表达式

mylist = [2, 1, 3, 5, 4]
mylist.sort()
print(mylist)   # [1, 2, 3, 4, 5]

mylist.reverse()
print(mylist)   # [1, 2, 3, 4, 5]

同时也有前缀表达式

mylist = [2, 1, 3, 5, 4]

sort_list = sorted(mylist)
print(sort_list)   # [1, 2, 3, 4, 5]

reverse_list = reversed(mylist)
print(list(reverse_list))   # [4, 5, 3, 1, 2]

Python 之父 Guido van Rossum 曾经解释过这个问题( #TODO: add link),有两个原因:

对于某些操作,前缀符比后缀更好读——前缀(和中缀)表示法在数学中有着悠久的历史,其视觉效果有助于数学家思考问题。我们可以简单地把公式 x*(a + b) 重写成 xa + xb ,但同样的事,以原生的面向对象的方式实现,就比较笨拙。
当读到 len(x) 时,我就 知道 这是在求某对象的长度。它告诉我了两点:返回值是一个整数,参数是某种容器。但当读到 x.len() 时,我必须事先知道某种容器 x,它实现了一个接口,或者继承了一个拥有标准 len() 方法的类。我们经常会目睹到这种混乱:一个类并没有实现映射(mapping)接口,却拥有 get() 或 keys() 方法,或者某些非文件对象,却拥有一个 write() 方法。

优雅易懂是 Python 奉行的设计哲学 ,len() 函数的前缀表达方式是最好的体现。我想起 Guido 对“为什么索引从 0 开始 ”的解释。其最重要的原因,也正是 0-based 索引最优雅易懂。

出自《The History of Python: Why Python uses 0-based indexing》
让我们来先看看切片的用法。可能最常见的用法,就是“取前 n 位元素”或“从第i 位索引起,取后 n 位元素”(前一种用法,实际上是 i == 起始位的特殊用法)。如果这两种用法实现时可以不在表达式中出现难看的 +1 或 -1,那将会非常的优雅。
使用 0-based 的索引方式、半开区间切片和缺省匹配区间的话(Python最终采用这样的方式),上面两种情形的切片语法就变得非常漂亮:a[:n] 和 a[i:i+n],前者是 a[0:n] 的缩略写法。

面向对象的编程语言自发明时起,就想模拟我们生活于其中的现实世界。可是什么类啊、接口啊、对象啊、以及它们的方法啊,这些玩意的毒,有时候蒙蔽了我们去看见世界本质的眼睛。

桌子类有桌子类的求长度方法,椅子类有椅子类的求长度方法,无穷无尽,可现实真是如此么?求长度的方法就不能是一种独立存在的对象么?它之所以存在,是因为有“对象”存在,而不是因为有某个类才存在啊。

求某个对象的长度,这种操作独立于对象之外而存在,并不是该对象内部所有的一种属性或功能。从这个角度理解,我们能够明白,为什么 Python 要设计出内置函数? 内置函数其实是对世界本质的一种捕捉。

为什么 list.sort() 没有返回排序列表?

在性能很重要的情况下,仅仅为了排序而复制一份列表将是一种浪费。因此, list.sort() 对列表进行了适当的排序。为了提醒您这一事实,它不会返回已排序的列表。这样,当您需要排序的副本,但也需要保留未排序的版本时,就不会意外地覆盖列表。

如果要返回新列表,请使用内置 sorted() 函数。此函数从提供的可迭代列表中创建新列表,对其进行排序并返回。例如,下面是如何迭代遍历字典并按keys排序:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值