Is arr.__len__() the preferred way to get the length of an array in Python?
在python中,下面是获取元素数量的唯一方法吗?
如果是这样,为什么要使用奇怪的语法?
1 2 3
| my_list = [1,2,3,4,5]
len(my_list)
# 5 |
同样适用于元组:
1 2 3
| my_tuple = (1,2,3,4,5)
len(my_tuple)
# 5 |
字符串,实际上只是字符数组:
1 2 3
| my_string = 'hello world'
len(my_string)
# 11 |
这样做的目的是为了使列表、元组和其他容器类型不需要显式地实现一个公共的.length()方法,相反,您可以检查len()中实现"magic"__len__()方法的任何内容。
当然,这似乎是多余的,但是长度检查实现可能会有很大的不同,即使在同一种语言中也是如此。一个集合类型使用.length()方法,而另一个类型使用.length属性,而另一个类型使用.count()属性,这并不少见。拥有一个语言级别的关键字可以统一所有这些类型的入口点。因此,即使您不认为是元素列表的对象也可以进行长度检查。这包括字符串、队列、树等。
len()的功能性也很适合于编程的功能风格。
1
| lengths = map(len, list_of_containers) |
- 伦和伦有什么区别?
- len()是语言命令,len()是容器类型的方法。
- len()是一个全局内置函数;uu len_uu()是对象可以实现的方法。len(foo)通常最后会调用foo.uu lenuuu()。
- 在这种情况下,不应该阻止直接调用len吗?因为有些人可能只是在不知情的情况下使用它。
- 如果直接调用它并不重要,双下划线表示它是一种特殊的方法,基本上是以您自己的风险使用。
- 但是为了干净,或者整洁,这些内部方法不应该被隐藏吗?
- 您提到,通过提供len(),每个容器不必实现.length()方法,但是如果每个类型仍然实现由len()调用的uu len_uuu()方法,这又有什么不同呢?len()处理不同的容器类型是否不同?
- …不讨论你的答案,只是一个不感兴趣的问题。我对Python的内部工作不太熟悉。
- @大卫:我想的更像是一个私人会员,所以你不能直接访问它。
- @琼:不,在python中没有什么是不可访问的,因为它的动态特性和duck类型。让来自Java/.NET的显式公有/私用的东西消失,它根本不适用于Python。我也花了一段时间来适应。
- @simon:len()并没有以不同的方式处理它们,只是不同的容器有不同的方式收集它们的长度(树容器可能只返回它拥有的顶级分支的数量,等等),len是实现这一点的通用入口点。
- @西蒙:关于"不需要全部实现.length()"这一点令人困惑。容器类型仍然需要实现返回其长度的方法;重点是它是一个标准化的协议,而不是必须为每个类型查找的特殊方法。双下划线表示这一点。
- 我试着改写我的答案,只是为了更清楚一点。
- 我同意CarlMeyer的说法,即不需要"显式实现"public.length()方法是误导性的,其核心含义是不正确的。任何东西仍然需要实现len,并且总是可以简单地实现他们自己的长度方法,命名为他们想要的任何东西——绕过len函数。所以我真的认为这是一些武断的奇怪,符合吉多如何看待世界。这可能与任何普遍的推理无关。
- 它可能是在Python中进行大的"对象"大修之前遗留下来的粗糙部分。如果你能想出更好的措词,不保证一个全新的答案,我很乐意更新我的。另外,请记住,我是为来自静态类型背景的人回答这个问题的,那里有更严格的类层次结构,所有容器实现承诺相应length()方法的接口。
- 字符串上的yes len()还返回字符串中的字符数。
- docs.python.org/3/faq/…提供了一些关于基本原理的附加信息。"功能效益"应该得到更多的解释:比较map(len, container_of_containers)和map(operator.methodcaller("len"), container_of_containers)。歧义参数与"a_line.length()"等情况有关,表示几何长度,而不是容器中的项目数。
- @它看起来更像返回Unicode代码点的数量
任何有意义的东西(列表、字典、元组、字符串等)的长度都可以在上面调用len。
1 2 3 4
| l = [1,2,3,4]
s = 'abcde'
len(l) #returns 4
len(s) #returns 5 |
"奇怪"语法的原因是,在内部,python将len(object)转换为object.__len__()。这适用于任何对象。因此,如果您定义了一些类,并且它有一个长度是合理的,那么只需在它上定义一个__len__()方法,然后就可以在这些实例上调用len。
python使用duck类型:它不关心对象是什么,只要它有适合当前情况的接口。当您对一个对象调用内置函数len()时,实际上是在调用它的内部 len 方法。自定义对象可以实现这个接口,len()将返回答案,即使对象在概念上不是序列。
有关接口的完整列表,请查看以下内容:http://docs.python.org/reference/datamodel.html基本自定义
获取任何python对象长度的首选方法是将其作为参数传递给len函数。在内部,python将尝试调用所传递对象的特殊__len__方法。
只需使用len(arr):
1 2 3 4 5 6 7
| >>> import array
>>> arr = array.array('i')
>>> arr.append('2')
>>> arr.__len__()
1
>>> len(arr)
1 |
- 通常我们只是假设,当一个新手说"数组"时,她是指"列表";+1是指没有假设的情况:)
- 我看到了,并且看到已经有一个使用列表的答案。我添加答案的唯一原因是,如果问题真的是使用数组的话,我会问:"好吧,是的,但是数组呢?"不管怎样,我对索维埃的回答投了反对票。-)
您可以使用len(arr)。如前面的答案中建议的那样,获取数组的长度。如果需要二维数组的尺寸,可以使用arr.shape返回高度和宽度
len(list_name)函数以list为参数,调用list的__len__()函数。
python建议用户使用len()而不是__len__()来保持一致性,就像其他人说的那样。但是,还有一些其他好处:
对于一些内置类型,如list、str、bytearray等,len()的cython实现走了一条捷径。它以C结构直接返回ob_size,这比调用__len__()快。
如果你对这些细节感兴趣,你可以读卢西亚诺·拉马尔霍写的《流畅的Python》。其中有许多有趣的细节,可以帮助您更深入地理解Python。