Frage zu for-schleifen und Listen
Ich bin noch nicht so fit in Python und hoffe, dass ihr mir bei folgendem Problem helfen könnt:
Ich möchte mithilfe einer for-Schleife verschiedene Listen erzeugen. Mit jedem Durchlauf erzeuge ich also eine Liste. Wie kann ich nun anschließend auf einzelne erzeugte Listen zugreifen, um die Listen aus allen Durchläufen miteinander zu vergleichen?
Ich hoffe, meine Frage ist verständlich, wenn nicht, bitte ich euch, mir zu sagen, was unverständlich ist
Ich möchte mithilfe einer for-Schleife verschiedene Listen erzeugen. Mit jedem Durchlauf erzeuge ich also eine Liste. Wie kann ich nun anschließend auf einzelne erzeugte Listen zugreifen, um die Listen aus allen Durchläufen miteinander zu vergleichen?
Ich hoffe, meine Frage ist verständlich, wenn nicht, bitte ich euch, mir zu sagen, was unverständlich ist
Wahrscheinlich hast du es nur falsch umgesetzt.Malinka hat geschrieben:Ich hatte dazu jetzt die Idee, außerhalb der for-Schleife eine neue Liste anzulegen, die den Inhalt der for-Schleife enthält, aber irgendwie scheint das wohl falsch zu sein.
Code: Alles auswählen
>>> import random
>>> datapool = []
>>> for _ in range(3):
data = [random.randint(1, 10), random.randint(1, 5), random.randint(1, 3)]
datapool.append(data)
>>> print datapool
[[6, 5, 3], [4, 5, 2], [8, 5, 3]]
>>> for entry in datapool:
print entry
[6, 5, 3]
[4, 5, 2]
[8, 5, 3]
Die Ausgabe nach der Schleife zeigt das Ergebnis.
Zuletzt geändert von /me am Donnerstag 29. August 2013, 16:25, insgesamt 1-mal geändert.
@Malinka: Du legst eine leere Liste an, und jede erzeugte Liste in der ``for``-Schleife hängst Du an diese Liste an.
Ergebnis:
Wobei man die äussere ``for``-Schleife hier wahrscheinlich auch durch eine „list comprehension” ersetzen könnte, ohne dass es zu unverständlich wird.
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from pprint import pprint
from random import randint
def main():
result = list()
for _ in xrange(10):
result.append([randint(1, 6) for _ in xrange(5)])
pprint(result)
if __name__ == '__main__':
main()
Code: Alles auswählen
[[6, 2, 2, 6, 1],
[6, 4, 2, 6, 6],
[2, 1, 3, 6, 5],
[1, 4, 1, 5, 4],
[2, 2, 4, 2, 2],
[2, 6, 3, 5, 5],
[4, 3, 1, 1, 2],
[5, 1, 5, 5, 3],
[5, 1, 3, 3, 6],
[2, 1, 5, 4, 4]]
random bzw. pprint waren ja nur zum Erzeugen der Daten bzw. für eine formatierte Ausgabe. Zudem ist das Importieren von Modulen nichts Schlimmes.Malinka hat geschrieben:Ohjeee, ich glaube, ich muss mir noch einiges an Grundlagen anschauen.
Gibt es vielleicht auch eine Version ohne Module zu importieren?
Du solltest auf jeden Fall das Tutorial für Python 2 oder das Tutorial für Python 3 durcharbeiten, je nachdem welche Version du einsetzt.
Du solltest dir nur abgewöhnen den Typ der Variablen in deren Namen mit aufzunehmen. Das bringt in den meisten Fällen keine Vorteile. Das kann im Gegenteil sogar von Nachteil sein wenn du mal auf eine andere Datenstruktur umstellst und der Name dann auf einmal irreführend ist.Malinka hat geschrieben:1. Neue Liste angelegt:
liste1 = []
2. Ans Ende der for-Schleife:
liste1.append(liste)
Das sollte doch reichen, oder? Sieht auf jeden Fall ganz gut aus
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ergänzend zu /me: Du solltest Dir auch abgewöhnen, Namen mit Indizes / Nummern zu versehen! Was sagt Dir denn ``liste1``? Dass sie zuerst an etwas gebunden wird? Dass sie irgend wie anders ist als nur ``liste``?
Im Regelfall macht man etwas falsch, wenn man Namen nummeriert! Entweder gibt es einfach einen treffenderen (s. z.B. ``datapool``, ``result`` - wenn es sich denn um ein Ergbnis an sich handelt), oder aber man hat lauter separate Namen a la ``a1``, ``a2``, ..., ``an`` - dann will man stattdessen eine *äußere* Datenstruktur benutzen, wie Du es ja anstrebst.
Im Regelfall macht man etwas falsch, wenn man Namen nummeriert! Entweder gibt es einfach einen treffenderen (s. z.B. ``datapool``, ``result`` - wenn es sich denn um ein Ergbnis an sich handelt), oder aber man hat lauter separate Namen a la ``a1``, ``a2``, ..., ``an`` - dann will man stattdessen eine *äußere* Datenstruktur benutzen, wie Du es ja anstrebst.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Okay, mit den Bezeichnungen habt ihr absolut recht.
Jetzt habe ich noch eine anderen Frage. (noch mit den unübersichtlichen Bezeichnungen)
Ich habe also nun eine Liste, die eine bestimmte Anzahl Listen (in meinem Fall jetzt 4) enthält. Nun möchte ich alle gemeinsamen Wörter, die also in jeder "Unterliste" vorkommen, wieder einer neuen Liste hinzufügen. Das muss ja irgendwie einfacher gehen, als nach meiner Variante. Ich muss vermutlich irgendwie eine range festlegen, damit er jeden Listenindex nach dem Vorkommen des Wortes überprüft. Ich bekomme es aber nicht hin
EDIT: Der Code soll also variabler werden, unabhängig von der Zahl der Listen.
Jetzt habe ich noch eine anderen Frage. (noch mit den unübersichtlichen Bezeichnungen)
Ich habe also nun eine Liste, die eine bestimmte Anzahl Listen (in meinem Fall jetzt 4) enthält. Nun möchte ich alle gemeinsamen Wörter, die also in jeder "Unterliste" vorkommen, wieder einer neuen Liste hinzufügen. Das muss ja irgendwie einfacher gehen, als nach meiner Variante. Ich muss vermutlich irgendwie eine range festlegen, damit er jeden Listenindex nach dem Vorkommen des Wortes überprüft. Ich bekomme es aber nicht hin
Code: Alles auswählen
liste2 = []
for wort in liste1[0]:
if wort in liste1[1]:
if wort in liste1[2]:
if wort in liste1[3]
liste2.append(wort)
@Malinka: Dazu solltest Du Dir mal den Datentyp `set` anschauen. Damit kann man deutlich einfacher und auch effizienter Schnittmengen bilden.
Edit: Und es geht auch ohne das man explizit Schleifen schreiben muss:
Edit: Und es geht auch ohne das man explizit Schleifen schreiben muss:
Code: Alles auswählen
from operator import and_
# ...
common_words = reduce(and_, word_sets)
Okay, mit das mit set habe ich grundsätzlich verstanden. Aber wie lege ich in der for-schleife die range fest? Ich muss ja, um die Schnittmenge zu bilden, z.B. "set1 & set2 & set3 & set4" durchführen. Wie ich anfange, weiß ich, schätze ich:
Code: Alles auswählen
for i in range(len(liste):
schnittmenge = set(wortliste[i])
# ?????
:
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Hui... Du hast - wie fast jeder Anfänger - mal wieder den Anti-Pattern schlecht hin eingebaut:
Vergiss sofort wieder, dass so etwas prinzipiell funktioniert
In Python iteriert man *direkt* über Elemente einer Liste (allgemein eines Iterables), wenn man sich für diese interessiert:
Und benenne endlich diese ``liste`` um!
Du kannst aus Deiner verschachtelten Listen-Struktur via ``map`` eine Liste von Sets machen:
Danach hat Dir BlackJack ja schon gezeigt, wie man mittels ``reduce`` einfach den Schnitt über alle Mengen bilden kann.
Du kannst Dir natürlich auch sofort Sets von Wörtern bauen - es sei denn, es gibt zu Beginn einen guten Grund dafür, diese erst einmal in einer Liste zu lassen.
Code: Alles auswählen
for i in range(len(liste):
# zugriff auf Elemente via Index: liste[i]
In Python iteriert man *direkt* über Elemente einer Liste (allgemein eines Iterables), wenn man sich für diese interessiert:
Code: Alles auswählen
for words in liste:
# words ist eine Sub-Liste in Deinem Falle
Du kannst aus Deiner verschachtelten Listen-Struktur via ``map`` eine Liste von Sets machen:
Code: Alles auswählen
word_sets = map(set, liste)
Du kannst Dir natürlich auch sofort Sets von Wörtern bauen - es sei denn, es gibt zu Beginn einen guten Grund dafür, diese erst einmal in einer Liste zu lassen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Zuerst solltest du dir `for i in range(len(list))` abgewoehnen, in Python kann man direkt ueber die Elemente iterieren und das will man meist auch. Sollte zusaetzlich noch der Index noetig sein, gibt es `enumerate`.
Hier zwei Ansaetze fuer die Schnittmenge:
Oder "manueller"
Dein Ansatz funktioniert nicht, weil du immer wieder `schnittmenge` ueberschreibst, statt sie zu aktualisieren.
Hier zwei Ansaetze fuer die Schnittmenge:
Code: Alles auswählen
In [20]: words = [['a', 'b', 'c'], ['a', 'd', 'e'], ['f', 'a', 'g']]
In [21]: word_intersection = reduce(set.intersection, map(set, words))
In [22]: word_intersection
Out[22]: set(['a'])
Code: Alles auswählen
In [23]: word_intersection = set(words[0])
In [24]: for sub_words in words:
....: word_intersection.intersection_update(set(sub_words))
....:
In [25]: word_intersection
Out[25]: set(['a'])
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
@cofi: In Deinem zweiten Ansatz könnte man beim zweiten Element in der for-Schleife anfangen
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ja, und man koennte einen Iterator benutzen und das erste Set mit `next` initialisieren .. aber ich wollte es einfach halten
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Okay, habe doch nicht die Finger davonlassen können.
@ cofi Habe jetzt eher deinen konservativeren Vorschlag genommen, da der doch für mich am besten nachvollziehbar ist und es so nach meinem Geschmack angepasst:
Habe ich die Funktionsweise jetzt richtig verstanden (siehe Kommentar)?
Wahrscheinlich lacht ihr jetzt, aber ich weiß nicht, warum in meinem Code aus &= hier &= gemacht wird...
@ cofi Habe jetzt eher deinen konservativeren Vorschlag genommen, da der doch für mich am besten nachvollziehbar ist und es so nach meinem Geschmack angepasst:
Code: Alles auswählen
vergleichsliste = set(wortliste[0])
for worte in wortliste:
#Ein Set der Worte aus der ersten "Sub-Liste" wird mit den Sets aus allen "Sub-Listen" verglichen und die Schnittmenge gebildet
vergleichsliste &= set(worte)
Wahrscheinlich lacht ihr jetzt, aber ich weiß nicht, warum in meinem Code aus &= hier &= gemacht wird...
@Malinka: Das liegt am Forum. Aber nicht nur deswegen solltes Du lieber die Methode verwenden. Da brauchst Du erstens die `worte` nicht in ein `set` umwandeln und zweitens wird nur `set` verwendet das aktualisiert wird, statt in jedem Schleifendurchlauf ein neues `set` mit einem Zwischenergebnis zu erstellen. Und lesbarer ist es auch, weil man bei einem Methodennamen leichter in der Dokumentation suchen kann als bei einem Operator.