一般来说,有没有一种有效的方法可以知道Python中的迭代器中有多少个元素,而不用遍历每个元素并计数?
当前回答
所以,对于那些想知道讨论总结的人。使用以下方法计算5000万长度生成器表达式的最终最高分:
len(列表(创)), Len ([_ for _ in gen]), Sum (1 for _ in gen), Ilen (gen) (from more_itertool), Reduce (c, i: c + 1, gen, 0),
按执行性能排序(包括内存消耗),会让你大吃一惊:
```
1: test_list.py: 8:0.492 KiB
gen = (i for i in data*1000); t0 = monotonic(); len(list(gen))
('list, sec', 1.9684218849870376)
2: test_list_compr.py: 8:0.867 KiB
gen = (i for i in data*1000); t0 = monotonic(); len([i for i in gen])
('list_compr, sec', 2.5885991149989422)
3: test_sum.py:8: 0.859 KiB
gen = (i for i in data*1000); t0 = monotonic(); sum(1 for i in gen); t1 = monotonic()
('sum, sec', 3.441088170016883)
4: more_itertools/more.py:413: 1.266 KiB
d = deque(enumerate(iterable, 1), maxlen=1)
test_ilen.py:10: 0.875 KiB
gen = (i for i in data*1000); t0 = monotonic(); ilen(gen)
(ilen, sec, 9.812256851990242)
5: test_reduce.py:8: 0.859 KiB
gen = (i for i in data*1000); t0 = monotonic(); reduce(lambda counter, i: counter + 1, gen, 0)
('reduce, sec', 13.436614598002052) ' ' '
因此,len(list(gen))是使用频率最高且占用内存较少的
其他回答
有点。你可以检查__length_hint__方法,但要注意(至少在Python 3.4之前,正如gsnedders所指出的那样),它是一个未记录的实现细节(在线程中跟随消息),它很可能消失或召唤鼻子恶魔。
否则,没有。迭代器只是一个只公开next()方法的对象。你可以根据需要多次调用它,它们最终可能引发也可能不会引发StopIteration。幸运的是,大多数时候这种行为对编码器来说是透明的。:)
不,任何方法都需要解析每个结果。你可以这样做
iter_length = len(list(iterable))
但是在无限迭代器上运行它当然不会返回。它还将消耗迭代器,如果你想使用内容,它将需要重置。
告诉我们你想要解决的真正问题可能会帮助我们找到更好的方法来实现你的实际目标。
编辑:使用list()会将整个可迭代对象一次性读入内存,这可能是不可取的。另一种方法是做
sum(1 for _ in iterable)
正如另一个人发布的那样。这样可以避免把它保存在记忆中。
所以,对于那些想知道讨论总结的人。使用以下方法计算5000万长度生成器表达式的最终最高分:
len(列表(创)), Len ([_ for _ in gen]), Sum (1 for _ in gen), Ilen (gen) (from more_itertool), Reduce (c, i: c + 1, gen, 0),
按执行性能排序(包括内存消耗),会让你大吃一惊:
```
1: test_list.py: 8:0.492 KiB
gen = (i for i in data*1000); t0 = monotonic(); len(list(gen))
('list, sec', 1.9684218849870376)
2: test_list_compr.py: 8:0.867 KiB
gen = (i for i in data*1000); t0 = monotonic(); len([i for i in gen])
('list_compr, sec', 2.5885991149989422)
3: test_sum.py:8: 0.859 KiB
gen = (i for i in data*1000); t0 = monotonic(); sum(1 for i in gen); t1 = monotonic()
('sum, sec', 3.441088170016883)
4: more_itertools/more.py:413: 1.266 KiB
d = deque(enumerate(iterable, 1), maxlen=1)
test_ilen.py:10: 0.875 KiB
gen = (i for i in data*1000); t0 = monotonic(); ilen(gen)
(ilen, sec, 9.812256851990242)
5: test_reduce.py:8: 0.859 KiB
gen = (i for i in data*1000); t0 = monotonic(); reduce(lambda counter, i: counter + 1, gen, 0)
('reduce, sec', 13.436614598002052) ' ' '
因此,len(list(gen))是使用频率最高且占用内存较少的
一个简单的方法是使用内置函数set()或list():
答:set()在迭代器中没有重复项的情况下(最快的方式)
iter = zip([1,2,3],['a','b','c'])
print(len(set(iter)) # set(iter) = {(1, 'a'), (2, 'b'), (3, 'c')}
Out[45]: 3
or
iter = range(1,10)
print(len(set(iter)) # set(iter) = {1, 2, 3, 4, 5, 6, 7, 8, 9}
Out[47]: 9
B: list()以防迭代器中有重复的项
iter = (1,2,1,2,1,2,1,2)
print(len(list(iter)) # list(iter) = [1, 2, 1, 2, 1, 2, 1, 2]
Out[49]: 8
# compare with set function
print(len(set(iter)) # set(iter) = {1, 2}
Out[51]: 2
def count_iter(iter):
sum = 0
for _ in iter: sum += 1
return sum
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录