"Leere Listen " mir for Schleife 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.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo,
ist es möglich sich mittels einer Schleife sich eine gewisse Anzahl an leeren Listen mit fortlaufender Nummer zu erzeugen?

Ich bekomme immer die Meldung "SyntaxError: can't assign to literal"

Danke schonmal u Gruß
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Wenn du anfängst Namen zu nummerieren, dann verwendest du die falsche Datenstruktur (bzw. gar keine) und möchtest Listen oder Tupel verwenden:

Code: Alles auswählen

[[] for _ in range(10)]
Außerdem bietet es sich an, die verwendeten Code zu zeigen. Bei den meisten Forumsmitgliedern scheint die Glaskugel gerade kaputt zu sein und Fehler raten bringt wenig Spaß. Auch haben Fehlermeldung eine ganze Menge zusätzlicher Information, daher kopiere beim nächsten Mal einfach die Fehlermeldung inklusive des gesamten Traceback. Und nicht nur den Teil, den du für wichtig hältst.
Das Leben ist wie ein Tennisball.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo zusammen,

Hintergrund ist das ich eine Liste habe, welche wie folgt aussieht:

....
135 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001015 1.20087E+00 0.00000E+00
136 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001016 9.26446E-01 0.00000E+00
137 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001017 9.51504E-01 0.00000E+00
138 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001018 9.50006E-01 0.00000E+00
139 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001019 9.50005E-01 0.00000E+00
140 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001020 1.20000E+00 0.00000E+00
141 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001021 7.78255E-01 0.00000E+00
142 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001022 1.26474E+00 0.00000E+00
143 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001024 1.20001E+00 0.00000E+00
144 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001025 9.00317E-01 0.00000E+00
.....

Nun gibt es zum jeder ID (1001015) innerhalb der Liste mehrere Werte welche ihr zugeordnet werden können(hier : 0.00000E+00 0.00000E+00 )
Diese sollen dann entsprechend dem Maximum sortiert werden.

Hat da jmd eine Idee?

Daanke und Gruß
BlackJack

@bob1704: Das was Du da zeigst ist keine Liste sondern ein Text. Was von dem sind denn die einzelnen Listenelemente? Und wie soll das Maximum gebildet werden? Und wofür brauchst Du die leeren Listen aus der Ausgangsfrage überhaupt?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

measurements = sorted([line.split() for line in data.split('\n')],
                      key=lambda m: max(float(m[1]), float(m[2])))
Allerdings bekommst du mit Sicherheit eine bessere Loesung, wenn du sagst, wie die Daten urspruenglich vorliegen (wahrscheinlich csv?) und was du anschliessend damit vorhast.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dazu bietet sich ein Dictionary an. Als Schlüssel verwendest du die ID und als Werte ein Tupel aus Minimum und Maximum. Je nach Verwendungszweck der Daten, könntest du das auch in eine SQLite-Datenbank schieben.
Das Leben ist wie ein Tennisball.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo,
BlackJack hat geschrieben:@bob1704: Das was Du da zeigst ist keine Liste sondern ein Text. Was von dem sind denn die einzelnen Listenelemente? Und wie soll das Maximum gebildet werden? Und wofür brauchst Du die leeren Listen aus der Ausgangsfrage überhaupt?
Die Idee war eine "leere Listen" zu erzeugen die wie die einzelnen ID´s heisen und anschliessend alle dazugehörigen Werte der entsprechenden Liste zu zuordnen und zu sortieren.
BlackJack

@bob1704: In dem Fall möchtest Du also ein Wörterbuch (`dict`) das jede ID auf eine Liste mit Werten abbildet.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

BlackJack hat geschrieben:@bob1704: In dem Fall möchtest Du also ein Wörterbuch (`dict`) das jede ID auf eine Liste mit Werten abbildet.
Hallo,

ja genau, un diese wenn möglich beginngend mit dem max. Wert absteigend sortiert...?!
BlackJack

@bob1704: Wörterbücher haben keine Reihenfolge der Einträge. Dann ist das mit der ID vielleicht gar nicht so wichtig?
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Doch die verschiedenene Werte müssten der ID schon noch zurodbar sein.
BlackJack

@bob1704: Die Werte der ID, ja, aber ein Wörterbuch ID → Werte macht ja nur Sinn wenn man den Zugriff über die ID auf die Werte benötigt. Wenn man das nicht braucht, reicht ja eine Liste von Listen wo Werte und ID jeweils in einer Unterliste stehen.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

@BlackJack:

Ja prinzipiell wäre folgendes auch ausreichend:

Code: Alles auswählen

Liste =[[ID][Wert1,Wert2....]] 
Wie wäre hier der Ansatz, wenn für jede ID eine Liste erzeugt werden muss.?
BlackJack

@bob1704: Das sind eigentlich alles ziemlich grundlegende Operationen auf den Grunddatentypen:

Code: Alles auswählen

In [14]: lines
Out[14]: 
['135 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001015 1.20087E+00 0.00000E+00\n',
 '136 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001016 9.26446E-01 0.00000E+00\n',
 '137 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001017 9.51504E-01 0.00000E+00\n',
 '138 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001018 9.50006E-01 0.00000E+00\n',
 '139 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001019 9.50005E-01 0.00000E+00\n',
 '140 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001020 1.20000E+00 0.00000E+00\n',
 '141 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001021 7.78255E-01 0.00000E+00\n',
 '142 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001022 1.26474E+00 0.00000E+00\n',
 '143 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001024 1.20001E+00 0.00000E+00\n',
 '144 0.00000E+00 0.00000E+00 0.00000E+00 0.0 spotweld beam ID 1001025 9.00317E-01 0.00000E+00\n']

In [15]: rows = (line.split() for line in lines)

In [16]: records = [(int(row[8]), map(float, row[1:3])) for row in rows]

In [17]: records
Out[17]: 
[(1001015, [0.0, 0.0]),
 (1001016, [0.0, 0.0]),
 (1001017, [0.0, 0.0]),
 (1001018, [0.0, 0.0]),
 (1001019, [0.0, 0.0]),
 (1001020, [0.0, 0.0]),
 (1001021, [0.0, 0.0]),
 (1001022, [0.0, 0.0]),
 (1001024, [0.0, 0.0]),
 (1001025, [0.0, 0.0])]
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo,
ich habe das ganze jtz wie folgt gelöst

Code: Alles auswählen

SWP_Anzahl = raw_input("Bitte SWp-Anzahl angeben: ")
i=0
#	
f = file("swforc.minmax", "w")
sheet_header()
for line in sw_forc_updated:
	swp_point = []
	axial_force = []
	shear_force = []
	swp_point.append(line.split()[8])
	for line in sw_forc_updated:
		if line.split()[8] == swp_point[0]:
			axial_value = line.split()[1]
			axial_value = float(axial_value)
			shear_value = line.split()[2]
			shear_value = float(shear_value)
			axial_force.append(axial_value)
			shear_force.append(shear_value)
#        print swp_point
#        print max(axial_force)
#        print max(shear_force)
	swp_point = int(swp_point[0])
	print >>f, "|\t %s  \t|\t\t %s  \t|\t %s  \t|" %(swp_point, max(axial_force),max(shear_force) )
	i=i+1
	sys.stdout.flush()
	if i >= SWP_Anzahl:
		break
f.close()			
Allerdings läuft das ganze nur sehr sher langsam..

Einer eine Idee?

Danke
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

@bob1704: Du gehst Deine Liste auch für jeden Listeneintrag nochmals komplett durch. Du solltest Deine shear_value und axial_value in einem Dictionary mit Key swp_point sammeln und zum Schluß, nachdem Du alle Einträge einmal durchgegangen bist die Maxima bilden.
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo,
habt ihr vllr einen Ansatz dafür?

Stehe im Moment etwas auf dem Schlauch ...

Danke
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Ungetestet ungefähr so:

Code: Alles auswählen

import collections
point_values = collections.defaultdict(lambda: ([],[]))

for row in sw_forc_updated:
    elements = row.split()
    axial, shear = point_values[elements[8]]
    axial.append(float(elements[1]))
    shear.append(float(elements[2]))

with file("swforc.minmax", "w") as swforc:
    swforc.write(''.join(
        '%s\t%s\t%s\n'%(swp_point, max(axial_force), max(shear_force))
        for swp_point, (axial_force, shear_force) in point_values.iteritems()
    ))
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Sirius3 hat geschrieben:Ungetestet ungefähr so:

Code: Alles auswählen

import collections
point_values = collections.defaultdict(lambda: ([],[]))

for row in sw_forc_updated:
    elements = row.split()
    axial, shear = point_values[elements[8]]
    axial.append(float(elements[1]))
    shear.append(float(elements[2]))

with file("swforc.minmax", "w") as swforc:
    swforc.write(''.join(
        '%s\t%s\t%s\n'%(swp_point, max(axial_force), max(shear_force))
        for swp_point, (axial_force, shear_force) in point_values.iteritems()
    ))
Danke funktioniert...

Allerdings habe ich nicht wirklich verstanden was du da machst....

Könntest noch 2-2 Sätze erläutern..?

Danke
BlackJack

@bob1704: Zu Deinem letzten Ansatz der so langsam war: Überleg doch mal wie oft dort was ausgeführt wird in Abhängigkeit von der Länge von `sw_forc_updated`.

Zum Beispiel wie oft Zeilen mit `split()` zerlegt werden. Wenn `sw_forc_updated` 1.000 Zeilen enthält, dann wird für jede Zeile noch einmal jede Zeile betrachtet. Also insgesamt 1.000·1.000=1.000.000 mal. Für jeden inneren und jeden äusseren Schleifendurchlauf wird mindestens einmal `split()` aufgerufen. Das wären dann 1.001.000 Aufrufe Minimum. Wenn die Werte in Spalte 8 eindeutig sind, dann kommen noch mal zwei Aufrufe pro Zeile hinzu, also Minimum 1.003.000 Aufrufe. Im schlechtesten Fall enthalten alle Zeilen den gleichen Wert in Spalte 8, dann sind es 3.001.000 Aufrufe. Wo eigentlich insgesamt nur 1000 notwendig wären, denn man müsste jede Zeile ja nur *einmal* in ihre Einzelteile zerlegen. Das sind 3 *Millionen* unnötige Aufrufe. Und diese Verschwendung steigt quadratisch mit der Anzahl der Zeilen. Bei 5.000 Zeilen hat man schon mindestens 25 Millionen unnötige Zerlegungen und bei 10.000 Zeilen sind es 100 Millionen. Minimum!

Das ist aber sowieso komisch gelöst, denn entweder sind die Werte in Spalte 8 eindeutig — dann braucht man die innere Schleife überhaupt nicht; oder die Werte können mehrfach vorkommen — dann würde für jedes Vorkommen aber völlig unnötigerweise die gleiche Aufwändige Berechnung jedes mal durchgeführt. Es kommt aber jedes mal das gleiche Ergebnis dabei heraus. Das macht keinen Sinn.
Antworten