簡體   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