当前位置:  开发笔记 > 编程语言 > 正文

有没有内置的方法来获取python中迭代的长度?

如何解决《有没有内置的方法来获取python中迭代的长度?》经验,为你挑选了5个好方法。

例如,Python中的文件是可迭代的 - 它们遍历文件中的行.我想计算行数.

一个快速的方法是这样做:

lines = len(list(open(fname)))

但是,这会将整个文件加载到内存中(一次).这相当违背了迭代器的目的(它只需要将当前行保留在内存中).

这不起作用:

lines = len(line for line in open(fname))

因为发电机没有长度.

有没有办法做到这一点,没有定义计数功能?

def count(i):
    c = 0
    for el in i: c += 1
    return c

编辑:澄清,我明白整个文件必须阅读!我只是不想在内存中一次性=).



1> Kamil Kisiel..:

没有遍历迭代并计算迭代次数,没有.这就是使它成为可迭代而不是列表的原因.这甚至不是特定于python的问题.查看经典的链表数据结构.查找长度是O(n)操作,涉及迭代整个列表以查找元素的数量.

正如上面提到的那样,你可以将你的功能减少到:

def count_iterable(i):
    return sum(1 for e in i)

当然,如果您要定义自己的可迭代对象,则可以始终实现__len__自己并在某处保留元素数.


罢工itertools.tee.我总是忘记它必须将原始迭代器中的数据放在某个地方,这直接违背了操作的要求.
那就对了.如果您必须使用整个iterable来获取计数,那么您将有效地将所有数据加载到tee的临时存储中,直到它被其他迭代器使用为止.

2> mcrute..:

如果你需要一个行数,你可以做到这一点,我不知道有任何更好的方法:

line_count = sum(1 for line in open("yourfile.txt"))



3> ttepasse..:

我已经使用了这个重新定义了一段时间了:

def len(thingy):
    try:
        return thingy.__len__()
    except AttributeError:
        return sum(1 for item in iter(thingy))


"谨慎使用"又名"我们都同意成年人",这是Python的原则之一.至少它是一次,一次.

4> wouter bolst..:

cardinality包提供了一个有效的count()函数和一些相关的函数来计算和检查任何iterable的大小:http://cardinality.readthedocs.org/

import cardinality

it = some_iterable(...)
print(cardinality.count(it))

在内部,它使用enumerate()并将collections.deque()所有实际的循环和计数逻辑移动到C级别,从而for在Python中循环得到相当大的加速.



5> Triptych..:

绝对不是,原因很简单,因为不能保证迭代是有限的.

考虑这个完全合法的生成函数:

def forever():
    while True:
        yield "I will run forever"

尝试计算此功能的长度len([x for x in forever()])显然不起作用.

正如您所指出的,迭代器/生成器的大部分用途是能够处理大型数据集而无需将其全部加载到内存中.您不能立即获得长度的事实应被视为权衡.


sum(),max()和min()也是如此,但这个聚合函数需要迭代.
我赞成这一点,主要是为了"绝对",这是不正确的.任何实现__len __()的东西都有一个长度 - 无限或无.
@Triptych是的,但正如跳跃所说,从"绝对"开始意味着普遍适用性,包括所有特殊情况.
是的,如果给出无限生成器,它将永远不会终止.但这并不意味着这个想法在所有情况下都毫无意义.文档字符串中的一个简单警告表明了这种限制就足以正确使用.
推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有