Liste mit tuple zu Liste mit ranges

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
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Hallo!

Ich möchte folgende Liste:

liste = [[(10, 13), (15, 22)], [(19, 24)], [(20, 25)]]

in solche umwandeln:

[[10, 11, 12, 15, 16, 17, 18, 19, 20, 21], [19, 20, 21, 22, 23], [20, 21, 22, 23, 24]]
Also quasie die tuples in ranges umwandeln.
Mein Versuch funktioniert nur bedingt:

Code: Alles auswählen

liste2 = []
liste3 = []
for b in liste:
    if len(b) > 1:
        for a in b:
            start = a[0]
            end = a[1]
            bereich = range(start, end)
            liste2.extend(bereich)         
    else:
        start = b[0][0]
        end = b[0][1]
        bereich = range(start, end)  
        liste3.append(bereich)
liste3.append(liste2)
liste3.sort()
print liste3
Die Liste funktioniert z.B. nicht:
[[(10, 13), (15, 22)], [(13, 14), (19, 24)], [(20, 25)]]

Weiss jemand Rat?
Stefanie
http://www.snowflake-sl.info/index.html
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

So ?

Code: Alles auswählen

multiliste_alt = [[(10, 13), (15, 22)], [(13, 14), (19, 24)], [(20, 25)]]
multiliste_neu = []
for liste in multiliste_alt:
    liste_neu = []
    for tupel in liste:
        liste_neu.extend(range(tupel[0],tupel[1]))
    multiliste_neu.append(liste_neu)
print multiliste_neu
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Oder als List Comprehension (x ist hierbei die Eingangs-Liste):

Code: Alles auswählen

[sum((range(start, stop) for (start, stop) in intervals), list())
 for intervals in x]
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@Trundle: Beeindruckend! :shock:
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Alternativ, da sum.__doc__ eigentlich nur von Zahlen spricht:

Code: Alles auswählen

from operator import add

[reduce(add, (range(start, stop) for (start, stop) in intervals))
 for intervals in x]
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Trundle hat geschrieben:Alternativ, da sum.__doc__ eigentlich nur von Zahlen spricht: ...
Ach, schade, gerade das mit sum() fand ich so genial. Auf die Idee, sum() für die Verkettung von Listen einzusetzen, wäre ich nämlich nie gekommen.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

from operator import add

def sum_(iterable, start=0):
    return reduce(add, iterable, start)

print sum_([1, 2, 3, 4])
print sum_([(1, 2), (2, 3)], tuple())


mehr macht des nicht, es ist also legitim das zum list flattening zu nutzen meiner Meinung nach :]
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Meine Lösung nochmal:

Code: Alles auswählen

from itertools import starmap, imap

def flatten(iterable):
    return sum(iterable, [])

def to_ranges(ranges):
    return flatten(starmap(range, imap(tuple, ranges)))

liste = [[(10, 13), (15, 22)], [(19, 24)], [(20, 25)]] 

assert map(to_ranges, liste) == [[10, 11, 12, 15, 16, 17, 18, 19, 20, 21], [19, 20, 21, 22, 23], [20, 21, 22, 23, 24]] 
BlackJack

Ein bisschen mehr mach `sum()` (leider) doch:

Code: Alles auswählen

In [2]: sum(['hallo', ' ', 'welt'], '')
---------------------------------------------------------------------------
<type 'exceptions.TypeError'>             Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.TypeError'>: sum() can't sum strings [use ''.join(seq) instead]
Das es diesen "Spezialfall" mit einer Ausnahme quittiert, finde ich sehr unglücklich. Die Argumentation für dieses Verhalten, nämlich dass das bei Zeichenketten quadratische Laufzeit hat, gilt für Listen nämlich auch.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Darüber hab ich tatsächlich noch nicht nachgedacht und werde jetzt jedenfalls ne andere implementation von flatten() nehmen :]
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Vielen Dank :shock:
List Compr. sind schon sehr beeindruckend...

Stefanie
http://www.snowflake-sl.info/index.html
Antworten