2016-09-08 15 views
1

私はイテレータを作成しました。私はレシピの成分を繰り返し、ビーガンの人がそれをできるかどうかをチェックしようとしています。クラス属性としてリストを渡すことができません

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 

あなたが見ることができるように、私はリストであるべき、*引数を渡すんだけど、私はこれを実行しようとするたびに、それは最初の単語を反復処理し、ワード「トマト」の文字をチェックします。私は反復子が成分を通過するようにし、何かがNONE_VEGAN_INGREDIENTリストにない場合は、そのままコードとして印刷します。私はどのようにリストを渡すことができますか?

+0

はビーガン(..)でVのための 'シンプルされていない場合:印刷(V) 'あなたの最後の行に相当する? – polku

+3

なぜiterを呼び出しているのですか?インスタンスを反復処理するだけではどうですか? –

答えて

3

あなたの問題のような__next__方法で解決することができると思いタプルではなく成分のインデックスを作成するため、ingredient[self.index]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) 

出力:

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 

あなたがあなた自身のコード内で呼び出すとStopIterationを上げるが、next(iterable)はそう同じことをするでしょう呼び出し、オブジェクト反復可能な作りのポイントは、あなたがITERATことができていますそれの上に直接eので、try/exceptの必要はありません。また私はリストでなければならないargsを渡していますは間違っています、argsはタプルです。あなたがNONE_VEGAN_INGREDIENTセットを作る確認するために、成分の多くを持っている場合

はまた、より効率的である:

NONE_VEGAN_INGREDIENT = {'egg', 'milk', 'honey', 'butter'} 
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 

いずれにせよ、私はこの問題ではなく__iter__を使用しての1本のまたは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に範囲外のインデックスのチェックを変更し、ループのために取り出します。これは私があなたのために行っていたと仮定した出力を生成する、働く:

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 

編集:固定の問題との声明

+0

'.format(component [self.index])'を '.format(self.ingredient_list [self.index])'に変更すると、1文字で奇妙な振る舞いを引き起こした修正が1件ありました。 – glibdud

+0

asdはvegan_ingredientsリストに含まれていませんが、私はあなたの意見を得ました。コードを修正しました。 – daladier

関連する問題