Variablen aus Dictionary-Keys dynamisch erzeugen?

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
Daniel26
User
Beiträge: 26
Registriert: Freitag 2. Juni 2017, 09:29

Moin,

ich habe ein Dictionary mit dezimalen Ziffern als Key. Als value zu den Keys ist ne Liste mit Strings hinterlegt.
also etwas so: [ 1: (abc,def,ghi),2:(klm,nop,qrs),3:(abc,def,geh),4:(..........}
Jetzt muss ich aus jedem ne Liste erzeugen, Name der Liste ist der Key, Inhalt der Liste ist das Value.
Also:
1=(abc,def,ghi)
2=(klm,nop,qrs)
3=(abc,def,geh)
4=(.........
....
....

Jetzt ist mir klar, das ich ne Zahl nicht als Name verwenden kann. Drum hätte ich dem ganzen jetzt "liste_" vorangestellt.
Nur wie bastlte ich da sganze zusammen?
Kann mir da jemand auf die Sprünge helfen?


Gruß

Daniel
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Gar nicht. Du bleibst bei deinem dict. Wie willst du denn sonst überhaupt mit den erzeugten Namen arbeiten? Wenn du Code schreibst, dann hat der doch Bezüge zu Variablennamen, die er schon kennt. Dynamisch kannst du also eh nix hinzufügen.

Was hast du denn wirklich vor?
Daniel26
User
Beiträge: 26
Registriert: Freitag 2. Juni 2017, 09:29

Die Listen sind Werte, die einer Funktion übergeben werden müssen, die ich in nen extra Thread packe.

Also z.B.
liste_1=threading.thread(target = funktion(dict[1]))

So in die richtung....
Ich erzeuge also für jeden Key nen extra Thread.

Gruß

Daniel
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@Daniel26: die Antwort ist hier die selbe. Erzeuge ein Wörterbuch mit den Threads als Values. Du erzeugst übrigens keine Threads, sondern rufst die Funktion direkt auf. Wenn es darum geht, viele Werte parallel auszurechnen, benutze besser Multiprocessing mit Maps.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Threading in Python ist nur quasi-parallel. Hat tiefe technische Gruende, aber wenn es dir dabei darum geht, das etwas schneller berechnet werden soll, dann solltest du wie von Sirius3 vorgeschlagen multiprocessing verwenden. Und zwar am besten einen Pool, der von alleine die Anzahl der CPU-Kerne als Worker-Nummer nimmt. Denn mehr ist eh nur overhead fuer das System.

Und dieser Anwendungsfall ist doch auch kein Grund, Variablennamen anlegen zu wollen. Ein simples

Code: Alles auswählen

for key, data in d.items():
      create_work_item(function, (key, data))
funktioniert wunderbar und ist flexibel. Was sollte da durch irgendwelche erzeugten Namen besser werden?
Daniel26
User
Beiträge: 26
Registriert: Freitag 2. Juni 2017, 09:29

Große Berechnungen sinds nicht.
Es geht drum dass ich einen Can-Bus abfragen möchte.

Ich hab ne Config mit Kürzeln, jedes Kürzel steht für nen bestimmten Wert. Hier gebe ich an, wie oft ich welchen Wert abfragen will (alle n Sekunden).

Momentan habe ich nen Loop mit nem Ticker.
Vor dem Loop wird die Config über nen Configparser gelesen und in ein Dict gepackt.
Im loop gehe ich das Dict durch und schaue, ob ein Wert zur Sekundenzahl passt (if not ticker%Sekunden_aus_dict: ).
Passt er, wird er in ne Liste gestellt.
Bin ich durch das Dict durch wird die Can-Abfrage mit den Werten aus der Liste in nem extra Thread gestartet (ich kann mehrere Werte in einem Rutsch abfragen), eine Sekunde geschlafen, der Ticker um eins hochgesetzt und es geht von vorne los.
Nen Extra Thread eigentlich nur, weil ich meinen Selbstgebauten Ticker nicht durch ne länger dauernde Abfrage ausbremsen will. Sicher dauert das durchkramen des Dict und das gruppieren auch nen Wimpernschlag.....

Bin ziemlich neu in Python, ich wusste es halt momentan nicht besser.

Gruß

Daniel
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir ist das immer noch nicht klar, aber ich bezweifele, dass du aus mehreren Threads mit deine CAN-Bus reden kannst. So etwas geht normalerweise in die Hose.

Stattdessen waerst du besser beraten, aus deinen verschiedenen Abfragen an den CAN-Bus einen kontinuierlichen Strom aus Wartezeit und naechster Abfrage zu berechnen.

Da in Python auch lokale und globale Variablen per dict-lookup nachgeschlagen werden (nur syntaktisch ueberzuckert) bringt das performance-maessig nix. Und es dauert Mikrosekunden. Wenn *das* ein Problem ist, dann hast du noch ein viel groesseres, denn dann ist Python (und eigentlich auch der PI) nicht mehr geeignet.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@Daniel26: Sobald IO in irgendeiner Form auftritt, ist das in der Regel um Größenordnungen langsamer als alles andere. Mikrooptimierungen machen dann noch ein Stück weniger Sinn als sonst.

Ich sehe da jetzt noch nicht dein Performance-Problem, aber ich würde auch den Weg vorschlagen, den __deets__ empfohlen hat. Als Datenstruktur würde sich eine Priority Queue anbieten (Modul `heapq`); wenn Füllen und Leeren der Queue in verschiedenen Threads passieren soll, bietet sich als threadsicheres Interface für `heapq` die Klasse `queue.PriorityQueue` an.

@__deets__: Zumindest in CPython werde lokale Variablen nicht in einem Dict gespeichert.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@narpfel: nicht? ah, kann sein, dass die Namen zu indizes kompiliert werden. Trotzdem geht ein solcher Lookup im Rauschen unter.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@__deets__: Ja, weil alle lokalen Variablen zur Compilezeit bekannt sind, kann man die (Mikro-) Optimierung durchführen, die Werte der Variablen in einem Array zu speichern.
Antworten