nested sequences - Entnestnung

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.
le_bub
User
Beiträge: 8
Registriert: Donnerstag 13. September 2007, 12:22

Dienstag 25. September 2007, 20:59

Halloechen!

Wiedermal ne Anfaengerfrage von mir:

Wie kommt man den bitte auf elegante Art und Weise von

liste = [('a', 'b', 'c'), ('a', 'l', 'h'), ('m', 'h', 'a')

auf

liste = ['a', 'b', 'c', 'a', 'l'. 'h', 'm', 'h', 'a'] ?

Vielen Dank fuer nen kleinen Tipp,

leBub
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Dienstag 25. September 2007, 21:17

Hallo le_bub!

Z.B. so:

Code: Alles auswählen

>>> liste = [('a', 'b', 'c'), ('a', 'l', 'h'), ('m', 'h', 'a')]
>>> flache_liste = []
>>> for item in liste:
...     flache_liste.extend(item)
...     
>>> flache_liste
['a', 'b', 'c', 'a', 'l', 'h', 'm', 'h', 'a']
>>>
mfg
Gerold
:-)
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lunar

Dienstag 25. September 2007, 21:42

Oder so:

Code: Alles auswählen

from itertools import chain

items = [('a', 'b', 'c'), ('a', 'l', 'h'), ('m', 'h', 'a')]
flattened = list(chain(*items))
print flattened
# >> ['a', 'b', 'c', 'a', 'l', 'h', 'm', 'h', 'a']
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Mittwoch 26. September 2007, 05:15

Oder so:
[wiki]Tipps und Tricks#Listen[/wiki]-> Verschachtelte Listen glätten

PS: Ich wollte eigentlich direkt auf die betreffende Seite verlinken, aber mit dem "ä" gabs Schwierigkeiten.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Mittwoch 26. September 2007, 08:14

Mein Firefox zeigt Sonderzeichen in Adresszeile in der %-Schreibweise an, also Verschachtelte_Listen_gl%C3%A4tten, damit klappts dann:

[wiki]Verschachtelte Listen glätten[/wiki]
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
lunar

Mittwoch 26. September 2007, 09:42

Der rekursive Generator hat aber einen kleinen Fehler, der in in diesem Fall, bei dem die inneren Listen Tupel sind, untauglich macht:

Code: Alles auswählen

def flatten(lst):
    for elem in lst:
        # diese Überprüfung schlägt fehl! Tupel sind keine Listen!
        if isinstance(elem, list):
            for i in flatten(elem):
                yield i
        else:
            yield elem
Es müsste also isinstance(elem, (list, tuple)) heißen!
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Mittwoch 26. September 2007, 19:21

Die Typüberprüfung ist eh fraglich. Normalerweise versucht man einfach, zu iterieren und fängt einen Fehler ab. Gut, da ist wieder eine Typüberprüfung notwendig, diesmal für Strings.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
le_bub
User
Beiträge: 8
Registriert: Donnerstag 13. September 2007, 12:22

Donnerstag 27. September 2007, 13:36

Herzlichen Dank wieder mal fuer eure Hilfe,

bub
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Donnerstag 27. September 2007, 14:38

Hi,

ich kann mich da nur der Meinung von Birkenfeld anschließen.

Mein Code den ich mir gebaut habe und immer in den utils habe ist folgender:

Code: Alles auswählen

def isiterable(v, exclude_string=True):
    if exclude_string and isinstance(v, basestring):
        return False
    try:
        iter(v)
    except:
        return False
    return True


def flatten(iterable):
    for x in iterable:
        if isiterable(x):
            for y in flatten(x):
                yield y
        else:
            yield x
Unterstützt das Ducktyping sehr. `isiterable` habe ich absichtlich so definiert das man strings mit `exclude_string` ausschließen kann.

Wem das zu lang ist, hier zusammengehackt:

Code: Alles auswählen

def flatten(iterable):
    def isiterable(v):
        if isinstance(v, basestring): return False
        try:iter(v)
        except: return False
        else: return True

    for x in iterable:
        if isiterable(x):
            for y in flatten(x):
                yield y
        else:
            yield x
BTW: Wenn man ausschließen kann das im iterable kein strings vorhanden sind, bin ich ganz klar für die erste Lösung von Lunar.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Donnerstag 27. September 2007, 14:40

Ich würde eine "isnewiter = lambda x: hasattr(x, '__iter__')" funktion basteln.
TUFKAB – the user formerly known as blackbird
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Donnerstag 27. September 2007, 14:53

Yes!! Viel eleganter und schneller. Thx :)

edit:
Ich glaube, dass kann man nun ins Wiki schieben ;)

Code: Alles auswählen

def flatten(iterable):
    for x in iterable:
        if hasattr(x, "__iter__"):
            for y in flatten(x):
                yield y
        else:
            yield x
BlackJack

Donnerstag 27. September 2007, 15:13

Das reicht nicht weil es 1. iterierbare Objekte gibt, die keine `__iter__()` Methode besitzen und 2. nur "Zufall" ist, dass Zeichenketten dazu gehören.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Donnerstag 27. September 2007, 15:32

BlackJack hat geschrieben:Das reicht nicht weil es 1. iterierbare Objekte gibt, die keine `__iter__()` Methode besitzen und 2. nur "Zufall" ist, dass Zeichenketten dazu gehören.
Also erstens fliegt diese Art der Iteration mit Python3 raus, und zweitens würde ich gerne wissen wo du solche Objekte rumliegen hast :-)
TUFKAB – the user formerly known as blackbird
BlackJack

Donnerstag 27. September 2007, 15:39

In Dateien auf meiner Festplatte. ;-) Die entstehen ab und zu ganz beiläufig wie zum Beispiel die `Namen`-Klasse hier: http://paste.pocoo.org/show/3954/
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Donnerstag 27. September 2007, 17:02

blackbird hat geschrieben:
BlackJack hat geschrieben:Das reicht nicht weil es 1. iterierbare Objekte gibt, die keine `__iter__()` Methode besitzen und 2. nur "Zufall" ist, dass Zeichenketten dazu gehören.
Also erstens fliegt diese Art der Iteration mit Python3 raus
Da wäre ich mir nicht sicher. Bisher ist es noch vorhanden, und es steht auch nicht in PEP 3100 als zu entfernen.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten