2012-05-16 3 views
22

Ich spielte mit Iterablen und genauer dem Operator yield in Python. Während Testgetriebene Entwicklung mit einem neuen iterable Schreiben zu beginnen, fragte ich mich, was der kürzeste Code, diesen einfachen Test für einen iterable passieren machen könnte:Was ist der einfachste Weg, um einen leeren Iterable mit Ausbeute in Python zu erstellen?

def test(): 
    for x in my_iterable(): 
     pass 

Die kürzeste Version, die ich denken konnte, war:

def my_iterable(): 
    for i in []: 
     yield i 

Ist es möglich, eine einfachere, kürzere oder schönere (pythonische) Version zu schreiben?

+1

Beachten Sie, dass wenn Ihr Test iterable leer ist und nichts produziert - wie gezeigt und in den meisten oder allen Antworten - Ihr Test keinen Code in der 'for' Schleife ausübt. – martineau

Antwort

18

Ja, es gibt:

return iter([]) 
+1

das ist nett, aber ich habe: 'F999' Warnung – lang2

11

Sie können die Funktionen Lambda und Iter verwenden, um ein leeres iterables in Python zu erstellen.

my_iterable = lambda: iter(()) 
1
def do_yield(): 
    return 
    yield None 

wenn Verwendung von yield für Sie wichtig ist, eine der anderen Antworten anders.

+0

+1 für die Beibehaltung' Ausbeute'. Nicht gut lesbar. :-) –

6

Wie wäre es

my_iterable = str 

dies passiert den Test.

ernst zu sprechen, Iterable im collections module bietet:

def __iter__(self): 
    while False: 
     yield None 

Diese "most pythonic" angesehen werden kann, weil das ist, was Python selbst verwendet.

Beachten Sie, dass technisch alle Antworten weit bieten so Iteratoren (__iter__ + next), nicht Iterables (nur __iter__).

+0

Akzeptiert wegen des Verweises auf die Python-Standardbibliothek. –

0

Eine andere Antwort, da ich eine völlig neue Lösung mit einem anderen Ansatz biete.

In einem von Bibliotheken, ich habe ein EmptyIterator wie

class EmptyIter(object): 
    __name__ = 'EmptyIter' 
    """Iterable which is False and empty""" 
    def __len__(self): return 0 
    def next(self): raise StopIteration # even that is redundant 
    def __getitem__(self, index): raise IndexError 

Es ist ein alternativer Ansatz, der die folgenden Eigenschaften verwendet:

  • alternative Iteration über Sequenzprotokoll (siehe here)
  • Alternative "Falschheit" Protokoll wie beschrieben here.
5

Eine andere Lösung, in Python 3 ist die neue yield from Syntax:

def empty_gen(): 
    yield from() 

Welche lesbar ist, und empty_gen als Generator halten.

+1

** Das ist es. ** Während Antworten wie 'lambda: iter (())' den Triebtrieb des Menschen nach Klugheit befriedigen, sind sie auch unlesbar und versagen bei der Erzeugung eines tatsächlichen * Generators. * Insbesondere 'isinstance (iter (()), types.GeneratorType) == False'. Wie der relative Erfolg von ['mypy'] (http://mypy-lang.org/) zeigt, sind Typen manchmal * wichtig *. Immer 'Ausbeute von', Python 3 Leute. –

Verwandte Themen