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



问题:如何快速高效地获取python生成器中的最后一项?

MWE

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出现故障。理论上它有8GB的RAM,但使用超过1-2GB会导致浏览器页面崩溃:D

这个问题已经回答了吗可能,但谷歌搜索"python get a generator的最后一项"会返回迭代器的结果。。。

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

对于一些生成器,你无法预测它们是否会结束(或者最后一个元素不确定):

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

这是有内存效率的,但生成器的内容现在已经丢失。

最新更新