我创建了一个迭代器。我试图重复食谱成分,检查一个纯素的人是否可以做到这一点。
class Vegan:
NONE_VEGAN_INGREDIENT = ['egg', 'milk', 'honey', 'butter']
def __init__(self, *args):
self.ingredient_list = (args)
self.index = -1
def __iter__(self):
return self
def __next__(self):
if self.index == len(self.ingredient_list):
raise StopIteration
for ingredient in self.ingredient_list:
if ingredient in Vegan.NONE_VEGAN_INGREDIENT:
self.index += 1
return ('{} is a vegan ingredient'.format(ingredient[self.index]))
else:
self.index += 1
return ('{} is NOT a vegan ingredient'.format(ingredient[self.index]))
iterable = Vegan('tomato', 'banana', 'asd', 'egg', 'tomato')
iterator = iter(iterable)
while True:
try:
print(next(iterator))
except StopIteration:
break
正如你所看到的,我传递* args,它应该是一个列表,但每当我尝试运行它时,它会遍历第一个单词,并检查单词' tomato&的字母#39 ;.我希望我的迭代器遍历成分,如果某些内容不在NONE_VEGAN_INGREDIENT列表中,则按原样在代码中打印。我怎样才能传入一个清单?
答案 0 :(得分:3)
您的问题是因为您索引的是成分而不是元组,unsigned long
应该是ingredient[self.index]
。
您可以简化代码以使其行为与您的行为相似,但可以通过使 args 可迭代来工作,这样您就可以按原样传递字符串而无需将它们放在列表中等..:
self.ingredient_list[self.index]
输出:
class Vegan:
NONE_VEGAN_INGREDIENT = ['egg', 'milk', 'honey', 'butter']
def __init__(self, *args):
self.ingredient_iter = iter(args)
def __iter__(self):
return self
def __next__(self):
ingredient = next(self.ingredient_iter)
if ingredient in Vegan.NONE_VEGAN_INGREDIENT:
return '{} is a vegan ingredient'.format(ingredient)
return '{} is NOT a vegan ingredient'.format(ingredient)
iterable = Vegan('tomato', 'banana', 'asd', 'egg', 'tomato')
for ele in iterable:
print(ele)
你在自己的代码中引发一个Stopiteration,但是调用In [2]: iterable = Vegan('tomato', 'banana', 'asd', 'egg', 'tomato')
In [3]: for ele in iterable:
...: print(ele)
...:
tomato is NOT a vegan ingredient
banana is NOT a vegan ingredient
asd is NOT a vegan ingredient
egg is a vegan ingredient
tomato is NOT a vegan ingredient
也会这样做,因此,使对象可迭代的重点是你可以直接迭代它,所以不需要try / except。另外我通过args,这应该是一个列表是不正确的,args是一个元组。
此外,如果你有很多成分要检查next(iterable)
,那么套装会更有效:
NONE_VEGAN_INGREDIENT
答案 1 :(得分:0)
以下是您问题的可能解决方案:
class Vegan:
NONE_VEGAN_INGREDIENT = ['egg', 'milk', 'honey', 'butter']
def __init__(self, *args):
self.ingredient_list = (args)
def __iter__(self):
self.index = 0
return self
def __next__(self):
if self.index >= len(self.ingredient_list):
raise StopIteration
ingredient = self.ingredient_list[self.index]
self.index += 1
if ingredient in Vegan.NONE_VEGAN_INGREDIENT:
return ('{} is a vegan ingredient'.format(ingredient))
else:
return ('{} is NOT a vegan ingredient'.format(ingredient))
iterable = Vegan('tomato', 'banana', 'asd', 'egg', 'tomato')
iterator = iter(iterable)
while True:
try:
print(next(iterator))
except StopIteration:
break
无论如何,我认为这个问题可以通过1行或2行解决,而不是像这样使用__iter__
和__next__
方法
答案 2 :(得分:0)
我认为您班级的问题在于您正在循环使用__next__()
方法中的元素。以下是使用您的代码的解决方案:
class Vegan:
NONE_VEGAN_INGREDIENT = ['egg', 'milk', 'honey', 'butter']
def __init__(self, *args):
self.ingredient_list = args
self.index = -1
def __iter__(self):
return self
def __next__(self):
if self.index == len(self.ingredient_list) - 1: # index is incremented
raise StopIteration
self.index += 1
if self.ingredient_list[self.index] in Vegan.NONE_VEGAN_INGREDIENT:
return ('{} is a vegan ingredient'.format(self.ingredient_list[self.index]))
else:
return ('{} is NOT a vegan ingredient'.format(self.ingredient_list[self.index]))
iterable = Vegan('tomato', 'banana', 'asd', 'egg', 'tomato')
iterator = iter(iterable)
while True:
try:
print(next(iterator))
except StopIteration:
break
我所做的就是将索引超出范围的检查更改为len() - 1
并删除for循环。这是有效的,产生我认为你想要的输出:
tomato is NOT a vegan ingredient
banana is NOT a vegan ingredient
asd is NOT a vegan ingredient
egg is a vegan ingredient
tomato is NOT a vegan ingredient
编辑:修复了if语句
的问题