Hallo Forum, wie kann ich in Python zwei Laufvariablen in einer for Schleife mit jeweils einem Wert aus zwei Listen/Arrays füllen? Geht das überhaupt? Den u.g. Code habe ich mal angehängt. Von Stdin wird ein File mit Parametername und Value gelesen. (z.B. Druck : 10\n Temp : 30\n usw.). Dieser Zeilenaufbau hat den Separator ":" und ist eigentlich sehr simpel. Nun lese ich den Parameternamen ins Array P[] und den Veluewert ins Array V[] ein. Das funktioniert soweit. Danach möchte ich nach dem Einlesen der Datei ein Wertepaar "Parametername,Vaulewert" in einer Schleife ausgeben, wobei ich die for Schleife wie folgt angebe. import sys P=[] # Parameter V=[] # Value for line in sys.stdin: (param,value)=line.split(': ') P.append(param) V.append(value) i=0 for (p,v) in (P[i],V[i]): <== Mein Problem print(p,v) i=i+1 Traceback (most recent call last): for (p,v) in (P[i],V[i]): ValueError: too many values to unpack (expected 2) Wahrscheinlich wird das Tupel (P[i],V[i]) nur einmal bei i=0 ausgewertet oder wo liegt das Problem. Danke für Eure Hilfe. Markus
Markus W. schrieb: > wie kann ich in Python zwei Laufvariablen in einer > for Schleife mit jeweils einem Wert aus zwei Listen/Arrays > füllen? Geht das überhaupt? Nicht daß ich wüßte. Was ginge, wäre der Zugriff über einen klassischen Schleifenzähler:
1 | for i in range(len(V)): |
2 | print(V[i], P[i]) |
> Von Stdin wird ein File mit Parametername und Value gelesen. > (z.B. Druck : 10\n Temp : 30\n usw.). Dieser Zeilenaufbau hat > den Separator ":" und ist eigentlich sehr simpel. > > Nun lese ich den Parameternamen ins Array P[] und den Veluewert > ins Array V[] ein. Das funktioniert soweit. Nimm' doch eine passende Datenstruktur dafür -- entweder eine Liste von Tupeln oder ein OrderedDict aus dem Paket collections.
Hallo, Danke euch beiden, das ging ja flott! Habe die Variante von anaconda genommen. >cat tmp.txt P1 : 1 P2 : 2 P3 : 3 >cat ./tmp.txt | ./plot_stat.py P1 1 P2 2 P3 3 Gruß Markus
Sheeva P. schrieb: > Nimm' doch eine passende Datenstruktur dafür -- entweder eine Liste von > Tupeln oder ein OrderedDict aus dem Paket collections. das ist eigentlich der Wichtige Hinweiss, du solltest deinen parameter nicht nur über den Index an den Value binden, der Python-way sowas zu machen wäre ein Tuple, Dict oder OrderedDict, um diese werte aneinader zu binden. Je nach dem was du dannch machst und weitern requierments ist einer dieser Datentypen zu wählen.
1 | parameter = dict() |
2 | for line in sys.stdin: |
3 | k , v = line.split(': ') |
4 | parameter.setdefault(k, v) |
5 | |
6 | |
7 | for key in parameter.keys(): |
8 | print(k, parameter[key]) |
wäre zum bespiel die lösung mit dictornary, wobei die wiedergabe bewust nicht mit items gemacht wurde um dir zu demonstieren das dein parameter in dem Fall der Key ist wo mit du den wert erhälst.
Markus W. schrieb: > Danke euch beiden, das ging ja flott! > > Habe die Variante von anaconda genommen. Keine gute Idee. Das kopiert die bereits gelesenen Daten in genau die Liste von Tupeln, in Du gleich die Originaldaten hättest einlesen können. Kostet temporär das doppelte an Speicher und natürlich die Kopieroperation. >>cat tmp.txt > P1 : 1 > P2 : 2 > P3 : 3 > >>cat ./tmp.txt | ./plot_stat.py > P1 1 > P2 2 > P3 3 Warum liest Du denn nicht gleich aus der Datei?
Hallo Sheeva, und imonbln, wie Ihr an meiner Fragestellung ja gesehen habt, bin ich noch kein Python Experte. Der Grund, warum ich es so mache ist einfach noch der Mangel an Erfahrung, was Python angeht. Der cat und die Pipe in meinem Beispiel zielte nur darauf ab Euch zu demonstrieren, was ich für einen Input bekomme. Ich bekomme aus einer Datei die genannten Wertepaare, wobei nicht alle Parameter für mich von Interesse sind. Die die mich interessieren möchte ich herausfiltern und entsprechend weiter verarbeiten (soll ein 2D xy-Plot werden). Den Vorschlag von "imonbln" mit dem Dictionary werde ich mir näher ansehen und umzusetzen versuchen. parameter = dict() for line in sys.stdin: k , v = line.split(': ') parameter.setdefault(k, v) for key in parameter.keys(): print(k, parameter[key]) Vom Aufbau ähnelt es ja Perl, wo ich mehr Erfahrung habe. Ich wollte es aber gezielt mit Python realisieren, um auch in dieser Skrtiptsprache etwas Übung zu bekommen. Danke für Eure Hilfe. Wenn es wieder irgendwo hackt, melde ich mich wieder. Markus
Markus W. schrieb: > Der cat und die Pipe in meinem Beispiel zielte nur darauf > ab Euch zu demonstrieren, was ich für einen Input bekomme. Ok, dann zeig' ich Dir mal eine Lösung:
1 | from argparse import ArgumentParser |
2 | from collections import OrderedDict |
3 | import matplotlib.pyplot as plt |
4 | |
5 | if __name__ == '__main__': |
6 | # Übergabe des Dateinamens: |
7 | parser = ArgumentParser(description='Daten aus Datei lesen') |
8 | parser.add_argument('filename', type=str, help='Dateiname') |
9 | args = parser.parse_args() |
10 | |
11 | # Daten lesen |
12 | data = OrderedDict() |
13 | with open(args.filename, 'r') as ifh: |
14 | for line in ifh: |
15 | k, v = map(str.strip, line.split(':')) |
16 | data[int(k)] = float(v) |
17 | |
18 | # ...zB plotten |
19 | plt.plot(data.keys(), data.values()) |
20 | plt.show() |
Bitte beachte, daß ich die eingelesenen Strings dabei gleich auch in int() und float()-Werte konvertiere; hier sind natürlich auch andere Datentypen wie datetime.datetime (hierzu bitte dateutils.parser.parse() anschauen) möglich. Deine Filter kannst Du, wahlweise vor oder nach der Zeile "k, v =...", oder auch nach dem kompletten Einlesen der Daten einbauen. In Deinem Beispiel kannst Du die Daten allerdings allerdings auch in zwei Listen speichern, weil Du die zum Plotten mit Matplotlib eh brauchst. Ich erzeuge die mit den Methoden keys() und values() des OrderedDict. > Den Vorschlag von "imonbln" mit dem Dictionary werde ich mir > näher ansehen und umzusetzen versuchen. Bitte bedenke dabei, daß so ein Python-Dictionary (ähnlich wie ein Perl-Hash und im Gegensatz etwa zu PHP) keine definierte Reihenfolge der Keys kennt. Wenn Du die Reihenfolge der Schlüssel behalten willst, brauchst Du deswegen das OrderedDict aus den collections.
Sheeva P. schrieb: > Markus W. schrieb: >> Danke euch beiden, das ging ja flott! >> >> Habe die Variante von anaconda genommen. > > Keine gute Idee. Das kopiert die bereits gelesenen Daten in genau die > Liste von Tupeln, in Du gleich die Originaldaten hättest einlesen > können. Kostet temporär das doppelte an Speicher und natürlich die > Kopieroperation. Im von Markus verwendeten Python 3 erzeugt zip() keine Liste, sondern liefert einen Iterator, der genau den von dir beschriebenen Nachteil vermeidet. Trotzdem hast du natürlich recht, dass man die Daten schon beim Einlesen in eine passende Datenstruktur packen sollte. Ob man für diese Datenstruktur besser eine Liste von Tupeln oder ein (ordered) Dictionary wählt, hängt davon ab, wie ein mehrfaches Auftreten des gleichen Parameternamens im Eingabedatenstrom behandelt werden soll.
Hallo Sheeva, hallo Yalu, und natürlich mc-Forumsleser. Danke für die detaillierten Vorschläge zu meinem Problem. In meinem konkreten Fall sieht es so aus. Ich erzeuge mir mittels eines bash Skriptes die beschriebenen Wertepaare aus Abfragen an eine sqlite Datenbank. Diese Abfragen liefern für bestimmte aufsteigende Zeitintervalle bestimmte Vorkommen von Ereignissen. Diese sollen gezählt werden (macht die DBk) und dann in Form eines Graphen visualisiert werden. Auf dem Quellsystem, wo die DBk läuft, kann ich kein Python an- wenden, deshalb bash. Am Zielrechner will ich die Daten entsprechend für eine Monatsstatistik aufbereiten. Bis dato wurde dies von meinem Kollegen via Excel gemacht. Um ihn diesen Arbeitsaufwand zu ersparen, will ich diese Aufgabe nun automatisieren, wie es eigentlich sinnvoll ist. Gleichzeitig wollte ich bei der Gelegenheit etwas in Python machen, da der Umfang noch recht überschaubar ist. Die Keys können mehrfach auftreten, wobei es von ihnen mehrere Typen gibt. Diese muss ich zusammenfassen, ihre Häufigkeit ermitteln und auf der Zeitachse entsprechend z.B. als Balken darstellen. Es soll so was wie ein Histogramm werden, das die Häufigkeit der Ereignisse auf der Zeitachse darstellt abhängig von bestimmten Initial-Zeitpunkten. Werde morgen entsprechend weiter machen und hoffe, dass alles so klappt, wie ich es mir vorgestellt habe. Danke nochmals für die ausführlichen Hinweise. Schönen Abend und bis zum nächsten Mal. Markus
Markus W. schrieb: > Die Keys können mehrfach auftreten, wobei es von ihnen mehrere > Typen gibt. Diese muss ich zusammenfassen, ihre Häufigkeit > ermitteln und auf der Zeitachse entsprechend z.B. als Balken > darstellen. Es soll so was wie ein Histogramm werden, das die > Häufigkeit der Ereignisse auf der Zeitachse darstellt abhängig > von bestimmten Initial-Zeitpunkten. Das von Sheeva verwendete matplotlib kann im übrigen auch gleich Histogramme out of the box. Diese Bibliothek war ursprünglich mal für Leute gedacht, die sich mit Matlab auskennen und kann daher auch eine Menge Dinge für die man sonst einen Riesenaufwand treiben muss. Edit: Link zur matplotlib webseite https://matplotlib.org/
:
Bearbeitet durch User
Hallo Forum, hallo anaconda, Habe mir gestern die buildin zip Funktion in Python angeschaut. und bei dieser Gelegenheit die vielen anderen buildin Funktionen gelistet bekommen. Vieles ist selbsterklärend aber manches davon muss man erst selbst verinnerlichen bei dieser Vielfalt. Return Value from zip() The zip() function returns an iterator of tuples based on the iterable object. If no parameters are passed, zip() returns an empty iterator If a single iterable is passed, zip() returns an iterator of 1-tuples. Meaning, the number of elements in each tuple is 1. If multiple iterables are passed, ith tuple contains ith Suppose, two iterables are passed; one iterable containing 3 and other containing 5 elements. Then, the returned iterator has 3 tuples. It's because iterator stops when shortest iterable is exhaused. Der dritte Passus zur zip-Funktion bestätigt , dass man sogar mehrdimensionales "zippen" bewerkstelligen kann, also sowas wie for (x,y,z...) in zip(X,Y,Z,...): Wobei die kürzeste Liste die Anzahl der Iterationen festlegt. In meinem Fall haben diese Listen ja die gleiche Länge. Bin begeistert von dieser Möglichkeit. Schwierigkeit für mich am Anfang besteht darin die für eine Problem nützlichen Bibliotheken zu finden und die entsprechenden Funktionen darin, um nicht das Rad wieder neu zu erfinden. Bis ich da den Überblick habe, wird es wohl noch etwas dauern. Die matplotlib Docs schaue ich mir gerade an und die zugehörigen Beispiele in der Gallery unter https://matplotlib.org/gallery/index.html Danke nochmals für diesen Hinweis. Markus
> Schwierigkeit für mich am Anfang besteht darin die für eine Problem > nützlichen > Bibliotheken zu finden und die entsprechenden Funktionen darin, um nicht > das > Rad wieder neu zu erfinden. > Bis ich da den Überblick habe, wird es wohl noch etwas dauern. > Das is nun mal immer so. Dagegen hilft z.B. erst mal wissen was/wohin man will in der Problemlösung entspr. benötigt man eine Basis in Grundlagen wie z.B Mathe/Menenlehre/Lineaalgebra/Funktionen/Graphen/Algorithmen/Datenstrukt uren/... und die da üblichen Fachbegriffe. Damit kann man -ggfs. übersetzt auf english- die libs abklopfen. Alternative: Doku zu den libs auswändig lernen und hoffen im passenden Moment vor gestelltem Problem den Glückstreffer abrufen zu können. Das Rad neu erfinden hilft nicht zuletzt das Verständnis für Problemstellung und (lib-)Implementation zu vertiefen, man kann so auch bereits erfundene Räder besser bewerten denn die haben nicht bedingungslos alle und immer passende Eigenschaften :-) Das gehört hin und wider dazu.
So ist es. Von meiner Seite ist dem Nichts mehr hinzuzufügen ;-) Markus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.