Was erwartest Du? Der Generator liefert eine islice-Instanz zurück.
Ein Generator, der genau ein Element liefert ist auch nicht sehr sinnvoll.
Was ist der Sinn dahinter, diesen Generator 10 mal in einer Schleife zu erzeugen?
islice benutzt man wie einen Generator oder jeden anderen Iterator mit einer for-Schleife oder ähnlichem. Ich verstehe nicht, was Du hier noch erreichen willst.
Liste wieder und wieder durchlaufen bis die Anzahl der zurückgegebenen Elemente stimmt
-
- User
- Beiträge: 407
- Registriert: Freitag 6. August 2010, 17:03
Eigentlich wollte ich bei jedem Aufruf des Generators ein weiteres Element nach der vorbestimmten Reihenfolge aus der Liste `numbers[]` zurückbekommen.
Gruß
Atalanttore
Gruß
Atalanttore
- __blackjack__
- User
- Beiträge: 13119
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Atalanttore: Und das bekommst Du nicht? Und mal so nebenbei ist die Frage ob das ein Generator ist dafür ziemlich irrelevant weil hier im ganzen Thema bis her nur die Eigenschaften eines iterierbaren Objekts genutzt werden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Jedesmal, wenn Du eine Generatorfunktion aufrufst, erhältst Du einen neuen Generator, von dem Du per next immer das einzige Element abfragst und das ist eben die islice-Instanz, so wie Du es programmiert hast.
Aber Du hast Dich da mit dem Generator verrannt, den brauchst Du nicht.
Aber Du hast Dich da mit dem Generator verrannt, den brauchst Du nicht.
Code: Alles auswählen
from itertools import islice, cycle
numbers = [1,2,3,4,5,6,7,8,9,10]
def liste(l):
return islice(cycle(l), 25)
for i in range(liste(numbers)):
print(i)
-
- User
- Beiträge: 407
- Registriert: Freitag 6. August 2010, 17:03
Im folgenden Beispiel wird auf die Anweisung, ob das Objekt ein `GeneratorType` ist, ein `True` zurückgegeben.__blackjack__ hat geschrieben: ↑Samstag 11. August 2018, 20:48 @Atalanttore: Und das bekommst Du nicht? Und mal so nebenbei ist die Frage ob das ein Generator ist dafür ziemlich irrelevant weil hier im ganzen Thema bis her nur die Eigenschaften eines iterierbaren Objekts genutzt werden.
Code: Alles auswählen
numbers = []
for i in range(65):
numbers.append(i)
def liste(l):
number = islice(cycle(l), 120000)
yield number
print(isinstance(liste(numbers), types.GeneratorType))
Darauf erscheint bei mir leider diese Fehlermeldung:Sirius3 hat geschrieben: ↑Samstag 11. August 2018, 20:55Code: Alles auswählen
from itertools import islice, cycle numbers = [1,2,3,4,5,6,7,8,9,10] def liste(l): return islice(cycle(l), 25) for i in range(liste(numbers)): print(i)
Code: Alles auswählen
Traceback (most recent call last):
File "/home/ata/source/test2.py", line 8, in <module>
for i in range(liste(numbers)):
TypeError: 'itertools.islice' object cannot be interpreted as an integer
Atalanttore
War ja auch falsch:
Code: Alles auswählen
for i in liste(numbers):
print(i)
- __blackjack__
- User
- Beiträge: 13119
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Atalanttore: Das ist ja schön das da True bei raus kommt und das ist ja auch richtig, aber das ändert nichts an meiner Bemerkung das die speziellen Eigenschaften eines Generators hier nirgends verwendet und damit auch nicht gebraucht werden. Hier wird nur iteriert und weder `send()`, `close()`, noch `throw()` aufgerufen. Solange man das nicht macht/braucht ist es Wurst ob man einen Generator oder ”nur” einen Iterator hat. Solange nicht `next()` selbst aufgerufen wird, sondern das ganze in einer ``for``-Schleife verarbeitet wird, braucht man nicht einmal einen Iterator, es reicht, dass das Objekt iterierbar ist, man also mit `iter()` einen Iterator von dem Objekt bekommen kann.
Dein Beispiel macht auch keinen Sinn.
Dein Beispiel macht auch keinen Sinn.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
-
- User
- Beiträge: 407
- Registriert: Freitag 6. August 2010, 17:03
Damit funktioniert es:Sirius3 hat geschrieben: ↑Samstag 11. August 2018, 21:09 War ja auch falsch:Code: Alles auswählen
for i in liste(numbers): print(i)
Code: Alles auswählen
from itertools import islice, cycle
numbers = [1,2,3,4,5,6,7,8,9,10]
def liste(l):
return islice(cycle(l), 25)
for i in liste(numbers):
print(i)
`send()` und `throw()` habe ich noch nie benutzt/gebraucht und `close()` nur für das Schließen eines Dateiobjekts.__blackjack__ hat geschrieben: ↑Samstag 11. August 2018, 21:14 @Atalanttore: Das ist ja schön das da True bei raus kommt und das ist ja auch richtig, aber das ändert nichts an meiner Bemerkung das die speziellen Eigenschaften eines Generators hier nirgends verwendet und damit auch nicht gebraucht werden. Hier wird nur iteriert und weder `send()`, `close()`, noch `throw()` aufgerufen. Solange man das nicht macht/braucht ist es Wurst ob man einen Generator oder ”nur” einen Iterator hat.
Also mit `iter()` kann man einen Iterator (Zeiger?) vom Objekt (Liste?) erstellen. Bei jedem Zugriff mit `next()` auf diesen Iterator wird automatisch das Element, das auf das zuletzt zurückgegebene Element im Iterator folgt, zurückgegeben. Habe ich das so richtig verstanden?__blackjack__ hat geschrieben: ↑Samstag 11. August 2018, 21:14 Solange nicht `next()` selbst aufgerufen wird, sondern das ganze in einer ``for``-Schleife verarbeitet wird, braucht man nicht einmal einen Iterator, es reicht, dass das Objekt iterierbar ist, man also mit `iter()` einen Iterator von dem Objekt bekommen kann.
Gruß
Atalanttore
- __blackjack__
- User
- Beiträge: 13119
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Atalanttore: Ob `cycle()` mit Indexwerten arbeitet, also Sequenztypen gesondert behandelt, wäre ein Implementierungsdetail. Das muss ja mit beliebigen iterierbaren Objekten funktionieren und nicht nur mit Sequenztypen wie Listen. Eine allgemeine Implementierung wäre also in zwei Phasen — in der ersten Phase werden die Elemente des Arguments zum Beispiel in einer Liste gespeichert *und* durchgereicht, und in der zweiten Phase wird entweder immer wieder über diese Liste iteriert. Ob nun mit Index oder über Iterator kann ja eigentlich egal sein. Wer's wissen möchte schaut halt in den Quelltext.
Ich wäre vorsichtig damit einen Iterator als Zeiger zu bezeichnen. Das Wort hat ja eine spezielle Bedeutung in der Programmierung und in dem Sinne ist ein Iterator kein Zeiger. Ein Iterator implementiert `__iter__()` — in der Regel liefert das Objekt dabei sich selbst zurück, und `__next__()` (Python 3) oder `next()` (Python 2). Letztere Methode liefert das nächste Element, oder löst eine `StopIteration` aus wenn es kein nächstes Element mehr gibt.
Ich wäre vorsichtig damit einen Iterator als Zeiger zu bezeichnen. Das Wort hat ja eine spezielle Bedeutung in der Programmierung und in dem Sinne ist ein Iterator kein Zeiger. Ein Iterator implementiert `__iter__()` — in der Regel liefert das Objekt dabei sich selbst zurück, und `__next__()` (Python 3) oder `next()` (Python 2). Letztere Methode liefert das nächste Element, oder löst eine `StopIteration` aus wenn es kein nächstes Element mehr gibt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
-
- User
- Beiträge: 407
- Registriert: Freitag 6. August 2010, 17:03
Ich habe das bestehende Beispiel auf die Verwendung eines Iterators umgebaut.
Allerdings haben die Anweisungen `__iter__()` und `__next__()` bei mir (Python 3.6) nicht funktioniert und ich musste die Unterstriche weglassen.
Gruß
Atalanttore
Code: Alles auswählen
from itertools import islice, cycle
numbers = []
for i in range(10):
numbers.append(i)
iterator = iter(islice(cycle(numbers), 25))
for i in range(26):
print(next(iterator))
Gruß
Atalanttore
- __blackjack__
- User
- Beiträge: 13119
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Atalanttore: Das macht keinen Sinn, warum machst Du das so umständlich? Jetzt hast Du einen zweiten Iterator und ein `i` das Du überhaupt nicht verwendest. Die erste Schleife ist auch unnötig kompliziert. Der Code sollte so aussehen:
`__iter__()` und `__next__()` sind die Methoden die das iterierbare Objekt und der Iterator haben müssen damit die Funktionen `iter()` und `next()` damit funktionieren. Also das iterierbare Objekt muss `__iter__()` implementieren und der Iterator beides.
(Das stimmt nicht so ganz, weil es noch andere Möglichkeiten gibt ein Objekt iterierbar zu machen, das hat aber eher historischen Wert.)
Code: Alles auswählen
from itertools import islice, cycle
numbers = list(range(10))
for number in islice(cycle(numbers), 25):
print(number)
(Das stimmt nicht so ganz, weil es noch andere Möglichkeiten gibt ein Objekt iterierbar zu machen, das hat aber eher historischen Wert.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Man muss noch nichtmal das `range`-Objekt in eine Liste umwandeln:
Code: Alles auswählen
from itertools import islice, cycle
for number in islice(cycle(range(10)), 25):
print(number)
- __blackjack__
- User
- Beiträge: 13119
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Stimmt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Dass islice schon ein Iterator ist, läßt sich leicht zeigen, indem man schaut, ob `iter` das selbe Element liefert
Code: Alles auswählen
from itertools import islice, cycle
iterator = islice(cycle(range(10)), 25)
print(iterator is iter(iterator))
# > True