Zeilen und Spalten in Listen vertauschen

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.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Zeilen und Spalten in Listen vertauschen

Beitragvon HWK » Freitag 15. Juni 2007, 19:41

Ich möchte eine Liste von Listen in eine andere Liste von Listen folgendermaßen konvertieren:

Code: Alles auswählen

c = 8
a = [range(i, c + i) for i in range(0, 20, 2)]
print 'a:\n', a
b = [[] for i in range(c)]
for x in a:
    for y, z in zip(b, x):
        y.append(z)
print 'b:\n', b
D.h. ich will Zeilen und Spalten in einer zweidimensionalen Liste vertauschen. Meine Lösung sieht aber etwas umständlich aus. Gibt es eventuell eine effektivere Lösung?
Danke
HWK
BlackJack

Beitragvon BlackJack » Freitag 15. Juni 2007, 19:58

*Effektiv* ist Deine Lösung. Man kann es einfacher schreiben. Aber ob's verständlicher oder *effizienter* ist, weiss ich nicht:

Code: Alles auswählen

In [13]: a
Out[13]:
[[0, 1, 2, 3, 4, 5, 6, 7],
 [2, 3, 4, 5, 6, 7, 8, 9],
 [4, 5, 6, 7, 8, 9, 10, 11],
 [6, 7, 8, 9, 10, 11, 12, 13],
 [8, 9, 10, 11, 12, 13, 14, 15],
 [10, 11, 12, 13, 14, 15, 16, 17],
 [12, 13, 14, 15, 16, 17, 18, 19],
 [14, 15, 16, 17, 18, 19, 20, 21],
 [16, 17, 18, 19, 20, 21, 22, 23],
 [18, 19, 20, 21, 22, 23, 24, 25]]

In [14]: map(list, zip(*a))
Out[14]:
[[0, 2, 4, 6, 8, 10, 12, 14, 16, 18],
 [1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
 [3, 5, 7, 9, 11, 13, 15, 17, 19, 21],
 [4, 6, 8, 10, 12, 14, 16, 18, 20, 22],
 [5, 7, 9, 11, 13, 15, 17, 19, 21, 23],
 [6, 8, 10, 12, 14, 16, 18, 20, 22, 24],
 [7, 9, 11, 13, 15, 17, 19, 21, 23, 25]]


Wenn die inneren Listen auch Tupel sein dürfen, reicht ``zip(*a)`` aus.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Samstag 16. Juni 2007, 06:27

Das sieht gut aus. Danke.
Ich habe in einem anderen Thread gelesen, dass 'reduce' irgendwann verschwinden soll. Gibt es evtl. auch eine andere, elegante Lösung für folgende Funktion in der Art 'if_any'?

Code: Alles auswählen

reduce(lambda x, y: x or bool(y), liste, False)
Danke
HWK
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Samstag 16. Juni 2007, 07:21

Einen ganz einfachen `for`-Loop:

Code: Alles auswählen

result = False
for y in liste:
    result = result or bool(y)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Beitragvon BlackJack » Samstag 16. Juni 2007, 09:19

Ab Python 2.5 könnte man die eingebaute `any()`-Funktion benutzen, davor tut's auch:

Code: Alles auswählen

def any(itarable):
    return True in (bool(item) for item in iterable)


Das hat in Gegensatz zur gezeigten ``for``-Schleife und dem ``reduce`` auch noch den Vorteil, dass abgebrochen wird, sobald das erste mal `True` vorkommt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Samstag 16. Juni 2007, 14:52

Stimmt, da war ich zu blind und habe nur den Code umgesetzt, ohne mir zu überlegen was er einfach tut.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Samstag 16. Juni 2007, 19:29

Guter Tip.
Danke
HWK
Benutzeravatar
Michael Schneider
User
Beiträge: 566
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Beitragvon Michael Schneider » Samstag 16. Juni 2007, 20:18

HWK hat geschrieben:Gibt es evtl. auch eine andere, elegante Lösung für folgende Funktion in der Art 'if_any'?

Code: Alles auswählen

reduce(lambda x, y: x or bool(y), liste, False)

Hallo,

wenn ich mir den Code ansehe, dann liefert die Funktion doch den ersten Wert der Liste, sofern er wahr ist und die Liste mindestens 2 Elemente besitzt. Also für eine Liste ["hallo", "welt"] würde sie 'hallo' zurückgeben. Wenn das ok ist, das nicht unbedingt True oder False bzw. 1 oder 0 zurückgegeben werden, kann man sich doch auch das bool(xyz) sparen und gleich "x or y" schreiben...
Bitte korrigiert mich, wenn ich mich irre.

Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...

Wer ist online?

Mitglieder in diesem Forum: Torsten_K