For-Schleife

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
dl13
User
Beiträge: 2
Registriert: Sonntag 19. Juni 2022, 18:36

Hallo zusammen,
ich habe ein (vermutlich für die meisten sehr einfache...) Frage zur For-Schleife. Ich habe folgende Liste:
list_1 = [ [1,1,1,1], [2,2,2,2], [3,3,3,3] ]

Mein Ziel ist es, dass eine neue Liste wie folgt geordnet ist:
list_2 = [ [1,2,3], [1,2,3], [1,2,3], [1,2,3] ]

Folgenden Code habe ich geschrieben, sodass die Reihenfolge schon mal stimmt:

Code: Alles auswählen

list_1 = [[1,1,1,1,1],[2,2,2,2,2],[3,3,3,3,3]]
list_2 =[]
    
for i in range(0,len(list_1[0])):
    print ("List: ", i)
    list_2.append([])
    for j in range(0,len(list_1)):
        print (list_1[j][i])
    
print (list_2)


Allerdings ist es mir nicht möglich, die Zahlen an der richtigen Stelle in list_2 einzufügen. Für einen Tipp bzw. eine Lösung wäre ich sehr dankbar!

Viele Grüße!
dl13
User
Beiträge: 2
Registriert: Sonntag 19. Juni 2022, 18:36

Das Problem ist gelöst...

Code: Alles auswählen

list_1 = [[1,1,1,1,1],[2,2,2,2,2],[3,3,3,3,3]]
list_2 =[]
    
for i in range(0,len(list_1[0])):
    list_2.append([])
    for j in range(0,len(list_1)):
        list_2[i].insert(j,list_1[j][i])
Beste Grüße!
Benutzeravatar
pillmuncher
User
Beiträge: 1482
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@dl13: Normalerweise iteriert man nicht mittels range() und Indizes über Listen, weil man direkt auf die Elemente zugreifen kann. Außerdem gibt es zip():

Code: Alles auswählen

>>> data = [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]
>>> list(map(list, zip(*data)))
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
Wenn die neuen Elemente auch Tupel sein können, wird es sogar noch einfacher:

Code: Alles auswählen

>>> list(zip(*data))
[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]
Merke: Die Standardbibliothek ist dein Freund.
In specifications, Murphy's Law supersedes Ohm's.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

`insert` ist in Deinem Fall unnötig kompliziert, weil es einem einfachen append entspricht.
Der Startwert von `range` ist als default 0, den muß man also nicht angeben.
Man sollte nicht über eine Index iterieren, wenn man es vermeiden kann:

Code: Alles auswählen

list_2 = []
for i in range(len(list_1[0])):
    row = []
    for inner_list in list_1:
        row.append(inner_list[i])
    list_2.append(row)
oder als List-Comprehension:

Code: Alles auswählen

list_2 = [
    [inner_list[i] for inner_list in list_1]
    for i in range(len(list_1[0]))
]
Trotzdem sollte man natürlich wissen, dass es für diese Fälle `zip` gibt.

pillmunchers und Deine Lösung unterscheiden sich im Detail, was passiert, wenn die inneren Listen unterschiedlich lang sind. Da wäre die Frage, was in diesem Fall passieren soll?
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Das Verfahren nennt man transponieren: https://de.wikipedia.org/wiki/Transponierte_Matrix
Wird z.B. auch bei Excel oft angewandt.

Kleine Ergänzung für Python 3.10:
https://docs.python.org/3/library/functions.html#zip

Code: Alles auswählen

# zu wenig Elemente in der letzten Liste
data = [[1, 1, 1, 1], [2, 2, 2, 2], [3]]
data_t = list(zip(*data, strict=True))
ValueError: zip() argument 3 is shorter than arguments 1-2
Wenn man noch eine ältere Python-Version als 3.10 nutzt, kann man strict nicht verwenden.
Ohne strict werden die anderen Elemente auch einfach ausgelassen und dann bekommt man so etwas als Ergebnis:
[(1, 2, 3)]
Wären in der letzten Liste 2 Elemente gewesen, hätte man zwei Tupel in der Liste.

Wenn es wichtig ist, dass alle Elemente verarbeitet werden und die fehlenden durch ein Platzhalter-Objekt ersetzt werden, kann man zip_longest verwenden.
https://docs.python.org/3/library/itert ... ip_longest

Code: Alles auswählen

from itertools import zip_longest


# zu wenig Elemente in der letzten Liste
data = [[1, 1, 1, 1], [2, 2, 2, 2], [3]]
data_t = list(zip_longest(*data))
print(data_t)
[(1, 2, 3), (1, 2, None), (1, 2, None), (1, 2, None)]
Durch das Argument fillvalue wird automatisch None vorgegeben, dass man ändern kann:

Code: Alles auswählen

from itertools import zip_longest


# zu wenig Elemente in der letzten Liste
data = [[1, 1, 1, 1], [2, 2, 2, 2], [3]]
data_t = list(zip_longest(*data, fillvalue="fehlt"))
print(data_t)
[(1, 2, 3), (1, 2, 'fehlt'), (1, 2, 'fehlt'), (1, 2, 'fehlt')]
Bei der Weiterverarbeitung der Liste muss dann natürlich die Ausnahme behandelt werden, dass "fehlt" z.B. einfach übersprungen werden soll.


Ich hoffe, das war nicht zu viel des Guten...
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten