[英]How to modify last element of a generator in python?
我有一個生成器,我想修改生成器的最后一個元素。 我想用另一個元素替換最后一個元素。 我知道如何檢索最后一個元素,但不知道如何修改它。
解決此問題的最佳方法是什么?
對於更多上下文,這是我想要做的:
for child in alexnet.children():
for children_of_child in child.children():
print(children_of_child);
我的生成器對象是: children_of_child
,第二個孩子的所有孩子都是:
Dropout(p=0.5)
Linear(in_features=9216, out_features=4096, bias=True)
ReLU(inplace)
Dropout(p=0.5)
Linear(in_features=4096, out_features=4096, bias=True)
ReLU(inplace)
Linear(in_features=4096, out_features=1000, bias=True)
我想用我自己的回歸網替換最后一層Linear(in_features=4096, out_features=1000, bias=True)
。 `
由於您使用的列表較小(即使就RAM而言,即使ResNet-150也“相當小”),因此我將使其易於理解和維護。 沒有“明顯”的方法可以檢測到您距離耗盡發電機僅一步之遙。
做到這一點的“好”(?)方法是在原始語言中編寫一個具有一個單元素前瞻性的包裝器生成器:在每次調用N
,包裝器中已經有元素N
了。 您從“實際”生成器(您發布的代碼)中獲取元素N+1
。 如果該元素存在,則通常返回元素N
如果該生成器已用盡,則將最后一個元素替換為所需的元素,然后返回更改。
范例 :
為簡單起見,我使用了range
代替您的原始生成器。
def new_tail():
my_list = list(range(6))
my_list[-1] = "new last element"
for elem in my_list:
yield elem
for item in new_tail():
print(item)
輸出:
0
1
2
3
4
new last element
有幫助嗎?
執行此操作的方法是迭代一個步驟,並在運行時跟蹤先前的值。 對於每個值,請產生前一個值。 當結束時,不產生最后一個先前的值,而是產生替換值:
def new_tail(it, tail):
sentinel = prev = object()
for value in it:
if prev is not sentinel:
yield prev
prev = value
yield tail
或者,您可以特別對待第一個元素,而不是使用前哨:
def new_tail(it, tail):
it = iter(it)
prev = next(it)
for value in it:
yield prev
prev = value
yield tail
您可能需要考慮使用完全空的迭代器會發生什么。 我不確定是要產生任何結果,產生替換值還是引發異常。 第一個版本產生替換值。 第二個……很好,它應該引發一個異常,但是從3.7開始,它發出DeprecationWarning
並且DeprecationWarning
產生任何結果,這可能不是您想要的行為。
無論如何,您可以將next
與sentinel
默認值一起使用,或者將except StopIteration:
next
。 然后,輕松執行所需的三個操作即可。
但是,如果您更抽象地考慮一下,則可以使它更簡單:如果您擁有所有相鄰的元素對,那么每個這樣的對中的第一個元素將為您提供除最后一個元素之外的所有元素。 因此,使用itertools
文檔中的pairwise
配方 :
def new_tail(it, tail):
for x, _ in pairwise(it):
yield x
yield tail
或者,如果您願意,甚至可以使用itertools.chain
和operator.itemgetter
使其成為單個表達式,盡管這可能有點愚蠢:
def new_tail(it, tail):
return chain(map(itemgetter(0), pairwise(it)), (tail,))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.