Inverses itertools.tee(), quasi izip() ohne Tupel gesucht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo zusammen,

wie kann man das folgende Problem elegant lösen? Ich versuche es mal in der von itertools bekannten Kurzschreibweise klar zu machen:

Code: Alles auswählen

func(p, q, ...) 	p0, q0, ... p1, q1, ... plast, qlast, ... 	
# z.B.
func('ABC', 'DEF') --> A D B E C F
Gesucht ist also eine Funktion, die sich jeweils das erste Element der gegeben Iterables nimmt, dieses zurückliefert und anschließend mit dem nächsten Element weitermacht usw. bis schließlich alle Elemente konsumiert wurden (inkl. ggf. nötiger Füllwerte bei ungleicher Länge).

Ich habe es mit Hilfe der flatten()-Funktion aus dem Brownie-Paket gelöst:

Code: Alles auswählen

In [8]: from itertools import izip_longest

In [9]: from brownie.itools import flatten

In [10]: a, b = range(5), range(5, 9)

In [11]: a, b
Out[11]: ([0, 1, 2, 3, 4], [5, 6, 7, 8])

In [12]: list(flatten(izip_longest(a, b)))
Out[12]: [0, 5, 1, 6, 2, 7, 3, 8, 4, None]
Also als Funktion dann z.B.:

Code: Alles auswählen

def merge(*iterables, **kwargs):
    fillvalue = kwargs.get('fillvalue')
    for item in flatten(izip_longest(*iterables, fillvalue=fillvalue)):
        yield item
Kann man das einfacher / eleganter lösen? Und wenn ja wie :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Du kannst `brownie.functional.compose` nutzen:

Code: Alles auswählen

>>> from itertools import izip_longest
>>> from brownie.itools import flatten
>>> from brownie.functional import compose
>>> merge = compose(flatten, izip_longest)
>>> list(merge(range(5), range(5, 9)))
[0, 5, 1, 6, 2, 7, 3, 8, 4, None]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Danke, das spart ja noch das manuelle Wrappen in eine Funktion. Aber das Prinzip als solches bleibt damit erhalten - scheint also nicht so schlecht zu sein als Ansatz :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Oder so (Python 3):

Code: Alles auswählen

>>> a = range(5)
>>> b = range(5, 9)
>>> list(itertools.chain(*itertools.zip_longest(a, b, fillvalue="-")))
[0, 5, 1, 6, 2, 7, 3, 8, 4, '-']
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn ich mich nicht täusche, entsteht beim Unpacking ein Tuple. Falls man diesen Zwischenschritt nicht haben möchte möchte, dann kann man auch ohne "Stern-Notation" über itertools.chain.from_iterable() gehen.
Antworten