繁体   English   中英

如何在 Python 生成器中获取最后一项

[英]How to Get Last Item in a Python Generator

问题:如何以快速且节省内存的方式获取 python 生成器中的最后一项?

兆瓦

import snscrape.modules.twitter as sntwitter
import time; start = time.time()

query = "Rooty Roo"

obj = sntwitter.TwitterSearchScraper(query)
print(obj) # didn't see much useful besides get_items

cnt = 0
items = obj.get_items()
for item in items:
  cnt += 1
  if cnt % 100 == 0:
    print(cnt)
  # end if
# end for
## the above seems ideal for memory-efficiency but 
## maybe super slow as I have no idea if there are 
## millions or billions of tweets in there. 
## Been running a few minutes and at ~17k so far.
## Not super ideal for playing around...

print(vars(tweet))
print("tweets: ", cnt)
print("executed in: ", time.time() - start)

我猜上面不是超级MWE,因为它依赖于一个包,但这是我第一次遇到生成器。 是什么引发了这个问题:)

上下文:我正在尝试了解有关此软件包如何工作的更多信息。 我开始阅读源代码,但认为四处玩耍和检查数据可能会更快¯\ (ツ)

内存高效上下文:我的笔记本电脑今年 10 岁了,我认为部分 RAM 出现故障。 理论上它有 8 GB RAM,但使用超过 1-2 GB 会导致浏览器页面崩溃:D

这个问题已经回答了吗? 可能,但谷歌搜索结果“python 获取生成器的最后一项”返回迭代器的结果......

不能(总是)确定生成器的最后一项。

在某些生成器中,您无法预测它们是否会结束(或最后一个元素不确定):

import random

def random_series():
    while x := random.randint(1, 10) > 1:
        yield x


# print random numbers from generator until 1 is generated
for x in random_series():
    print(x)

其他人将永远继续下去:

def natural_numbers():
    n = 0
    while True:
        n += 1
        yield n

# prints the first 10 natural numbers, but could go on forever
g = natural_numbers()
for _ in range(10):
    print(next(g))

但是,每个生成器都是一个迭代器,您可以尝试获取最后一个项目(或项目的数量),就像任何其他不明确告诉您或允许索引的迭代器一样。

对于执行以下操作的迭代器:

# if i is some iterator that allows indexing and has a length:
print('last element: ', i[-1])
print('size: ', len(i))

对于没有(但至少结束)的迭代器:

print('last element: ', list(i)[-1])
print('size: ', len(list(i)))

但是,如果您在无限生成器上尝试这样做,您的代码将挂起,或者更可能在它用完将列表放入的内存时崩溃。 另外,请注意,每次调用list(i)时,它都会构造一个新列表,因此如果您多次需要该列表,您可能希望将结果分配给变量以节省时间。

在你的情况下:

items = list(obj.get_items())
print("tweets: ", len(items))
print("last tweet: ", items[-1])

注意:正如用户@kellybundy 指出的那样,创建列表并不是非常节省内存。 如果您不关心除最后一个元素之外的实际内容,则可以使用:

for n, last in enumerate(obj.get_items()):
    pass
# n will be the number of items - 1 and last will be the last item

这是节省内存的,但生成器的内容现在丢失了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM