亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將“ yield from”語句轉換為Python 2.7代碼

將“ yield from”語句轉換為Python 2.7代碼

繁星coding 2019-11-30 15:08:45
我在下面的Python 3.2中有一個代碼,我想在Python 2.7中運行它。我確實進行了轉換(已經missing_elements在兩個版本中都放了代碼),但是我不確定這是否是最有效的方法?;旧?,如果函數的yield from上半部和下半部有兩個類似下面的調用,會發生什么情況missing_element?是否將兩個半部分(上半部分和下半部分)中的條目彼此追加到一個列表中,以便父遞歸函數與yield from調用一起使用并將這兩個半部分一起使用?def missing_elements(L, start, end):  # Python 3.2    if end - start <= 1:         if L[end] - L[start] > 1:            yield from range(L[start] + 1, L[end])        returnindex = start + (end - start) // 2# is the lower half consecutive?consecutive_low =  L[index] == L[start] + (index - start)if not consecutive_low:    yield from missing_elements(L, start, index)# is the upper part consecutive?consecutive_high =  L[index] == L[end] - (end - index)if not consecutive_high:    yield from missing_elements(L, index, end)def main():    L = [10, 11, 13, 14, 15, 16, 17, 18, 20]    print(list(missing_elements(L, 0, len(L)-1)))    L = range(10, 21)    print(list(missing_elements(L, 0, len(L)-1)))def missing_elements(L, start, end):  # Python 2.7    return_list = []                    if end - start <= 1:         if L[end] - L[start] > 1:            return range(L[start] + 1, L[end])    index = start + (end - start) // 2    # is the lower half consecutive?    consecutive_low =  L[index] == L[start] + (index - start)    if not consecutive_low:        return_list.append(missing_elements(L, start, index))    # is the upper part consecutive?    consecutive_high =  L[index] == L[end] - (end - index)    if not consecutive_high:        return_list.append(missing_elements(L, index, end))    return return_list
查看完整描述

3 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

如果您不使用收益率*,則可以隨時將其轉換為:


yield from foo

…變成這樣:


for bar in foo:

    yield bar

可能會有性能成本**,但從語義上講永遠不會有差異。


是否將兩個半部分(上半部分和下半部分)中的條目彼此追加到一個列表中,以使父遞歸函數與call的收益并同時使用這兩個半部分?


沒有!迭代器和生成器的全部要點是,您無需構建實際的列表并將它們附加在一起。


但是效果是相似的:您只是從一種收益,然后從另一種收益。


如果您將上半部分和下半部分視為“懶惰列表”,則可以,您可以將其視為“懶惰附加”,它會創建一個較大的“懶惰列表”。而且,如果您調用list父函數的結果,那么您當然會得到一個實際值list,該值等于將如果執行yield list(…)而不是所獲得的兩個列表加在一起yield from …。


但是我認為反過來更容易想到:它的作用與for循環完全相同。


如果將兩個迭代器保存到變量中并進行循環itertools.chain(upper, lower),則與在第一個循環然后在第二個循環上進行相同,對嗎?沒什么區別。實際上,您可以實現chain如下:


for arg in *args:

    yield from arg

*不是生成器產生給調用者的值,而是生成器內部的yield表達式本身的值(使用send方法從調用者產生),如PEP 342中所述。您沒有在示例中使用這些。而且我敢打賭您不在您的真實代碼中。但是協程式代碼通常使用yield from表達式的值- 有關示例,請參閱PEP 3156。此類代碼通常取決于Python 3.3生成器的其他功能-特別是StopIteration.value來自引入了同一PEP 380的新功能yield from-因此必須將其重寫。但是,如果沒有,您可以使用PEP來向您顯示完整的,混亂的等價物,當然您也可以減少不需要的部分。而且,如果您不使用表達式的值,它將縮減為上面的兩行。


**數量不多,除了使用Python 3.3或完全重組代碼外,您無能為力。這與將列表解析轉換為Python 1.5循環完全相同,或者在XY版本中進行了新的優化并且您需要使用舊版本時,則與其他情況完全相同。


查看完整回答
反對 回復 2019-11-30
?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

我只是碰到這個問題,我使用的是一個有點困難,因為我需要返回值的yield from:


result = yield from other_gen()

不能將其表示為簡單的for循環,但可以用以下方式重現:


_iter = iter(other_gen())

try:

    while True: #broken by StopIteration

        yield next(_iter)

except StopIteration as e:

    if e.args:

        result = e.args[0]

    else:

        result = None

希望這將幫助遇到相同問題的人們。:)


查看完整回答
反對 回復 2019-11-30
?
慕田峪9158850

TA貢獻1794條經驗 獲得超8個贊

用for循環替換它們:


yield from range(L[start] + 1, L[end])


==>


for i in range(L[start] + 1, L[end]):

    yield i

關于元素也是如此:


yield from missing_elements(L, index, end)


==>


for el in missing_elements(L, index, end):


查看完整回答
反對 回復 2019-11-30
  • 3 回答
  • 0 關注
  • 782 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號