[英]Return generator VS iterate with while until None
從下面的兩個選項中,什么是更有吸引力的(可讀代碼,更多pythonic,效率等),用於遍歷可迭代,並且如果將來我想添加更多邏輯(例如,對每個返回值添加1)?
一個選項返回生成器,另一個返回下一項,所有迭代完成后返回None
。
有沒有更好的方法? 如果是,為什么? 是否存在某些方法沒有的局限性?
class Option1():
def __init__(self):
self.current = 0
def get_next_batch(self, my_list):
if self.current == len(my_list):
self.current = 0
return None
self.current += 1
return [my_list[self.current-1]]
class Option2():
def __init__(self):
self.current = 0
def get_next_batch(self, my_list):
while self.current < len(my_list):
yield [my_list[self.current]]
self.current += 1
self.current = 0
raise StopIteration()
用法:
o1 = Option1()
o2 = Option2()
arr = [1,2,3,4,5]
a = o1.get_next_batch(arr)
while a is not None:
print a
a = o1.get_next_batch(arr)
for item in o2.get_next_batch(arr):
print item
兩種情況下的輸出:
[1]
[2]
[3]
[4]
[5]
您幾乎可以肯定要選擇第二個。 更少的線路,更少的出錯機會。
但是,看到您不在迭代器外部使用current
,我只會將整個過程優化為:
def get_next_batch(my_list):
for item in my_list:
yield [item]
arr = [1,2,3,4,5]
for item in get_next_batch(arr):
print item
旁點。 始終使您的類從python 2.7中的object
繼承,並且不要提高StopIteration
來終止python中的生成器-不推薦使用的行為可能導致bug。 使用return
代替。 例如。
def get_next_batch(my_list):
for item in my_list:
if item > 3:
return
yield [item]
batched = list(get_next_batch([1,2,3,4,5]))
expected = [[1], [2], [3]]
print batched == expected
您可以整理Option1
以使其易於在for循環中使用。 為此,您可以使用迭代器協議。 那是一個__iter__
方法,它返回self
和一個next
方法來獲取下一個項目。 例如。
class UsingNext(object):
def __init__(self, mylist):
self.current = 0
self.mylist = mylist
def __iter__(self):
return self
def next(self): # __next__ in python 3
if self.current >= len(self.mylist):
raise StopIteration
if self.current == 2:
self.current += 1
return "special"
item = self.mylist[self.current]
self.current += 1
return [item]
class UsingYield(object):
def __init__(self, mylist):
self.mylist = mylist
def __iter__(self):
for current, item in enumerate(self.mylist):
if current == 2:
yield "special"
continue
yield [item]
arr = range(1, 6)
# both print
# [1]
# [2]
# special
# [4]
# [5]
for item in UsingNext(arr):
print item
for item in UsingYield(arr):
print item
在我看來,生成器版本更干凈,更易於理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.