Liste/Tupel modifizieren

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
SoB
User
Beiträge: 3
Registriert: Dienstag 19. September 2017, 13:17

Hallo, ich bin python-Einsteiger und hoffe ihr seid nachsichtig mit mir ;-)
Ich möchte folgendes tun. Ich habe eine Liste

Code: Alles auswählen

datalist=[(0.0, 0.0, 1000.0), (-0.5, -0.5, 950.0), (0.5, -0.5, 850.0), (-0.5, 0.5, 850.0), (0.5, 0.5, 950.0)]
und möchte diese folgendermaßen modifizieren: Die ersten beiden Einträge in den einzelnen Tupel sollen jeweils mit 100 multipliziert werden, sodass

Code: Alles auswählen

datalist_mod=[(0.0, 0.0, 1000.0), (-50, -50, 950.0), (50, -50, 850.0), (-50, 50, 850.0), (50, 50, 950.0)]
.

In Matlab würde ich es als Matrix schreiben und so lösen:

Code: Alles auswählen

matrix_mod=[matrix(:,[1,2])*100,matrix(:,3)]
aber wie geht das mit einer Liste in Python? Ich fürchte, ich habe das Konzept noch nicht richtig durchschaut. Warum ist z.B. "datalist[:][0]=datalist[0][:]". Beides gibt mir das erste Tupel in der Liste datalist. Intuitiv hätte ich erwartet, dass eins von beiden die jeweils ersten Einträge der Tupel zurückgibt.
Zuletzt geändert von SoB am Dienstag 19. September 2017, 14:05, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

In Python machst du mit

liste[:]

eine Kopie der ganzen Liste, und davon das erste Element ist dann natuerlich (0, 0, 100).

liste[0][:]

ist dann das erste Element der Liste, und davon eine Kopie. Also gleich dem ersten Ausdruck.

Wenn du von matlab kommst, dann wirst du sicher mit NumPy arbeiten wollen/muessen. Und damit sollte dein Problem so zu loesen sein:

Code: Alles auswählen

>>> import numpy as np
>>> a = np.array(datalist)
>>> a.shape
(5, 3)
>>> a[:,0:2] * 100
array([[    0.,     0.,  1000.],
       [  -50.,   -50.,   950.],
       [   50.,   -50.,   850.],
       [  -50.,    50.,   850.],
       [   50.,    50.,   950.]])
SoB
User
Beiträge: 3
Registriert: Dienstag 19. September 2017, 13:17

Vielen Dank für die Erklärung. Ich denke wohl noch zu sehr "matlab-mäßig". In numpy werde ich mich mal einarbeiten, das klingt interessant für mich. Kurze Rückfrage zu dem Code: Wenn ich

Code: Alles auswählen

import numpy as np
datalist=[(0.0, 0.0, 1000.0), (-0.5, -0.5, 950.0), (0.5, -0.5, 850.0), 
		(-0.5, 0.5, 850.0), (0.5, 0.5, 950.0)]
a = np.array(datalist)
a[:,0:2] * 100
ausführe liefert das bei mir etwas anderes, nämlich:

Code: Alles auswählen

array([[  0.0,   0.0], 
       [-50.0, -50.0], 
       [ 50.0, -50.0], 
       [-50.0,  50.0],
       [ 50.0,  50.0]], 'd')
Es fehlt also die dritte Komponente.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ah, my bad. Ich hatte zuerst in-place multipliziert. Das solltest du auch tun, dann musst du aber entweder vorher eine Kopie machen falls du die Original Daten noch brauchst, oder eben nicht.

Also

Code: Alles auswählen

>>> b = np.array(a) 
>>> b[:,:2] *= 100
SoB
User
Beiträge: 3
Registriert: Dienstag 19. September 2017, 13:17

Ach ja, so geht's, danke :)
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Fix könnte man das mittels list-comprehension zusammen mit tuple-unpacking lösen:

[codebox=pycon file=Unbenannt.txt]
>>> data = [(0.0, 0.0, 1000.0), (-0.5, -0.5, 950.0), (0.5, -0.5, 850.0)]
>>> [(x * 100, y * 100, z) for x, y, z in data]
[(0.0, 0.0, 1000.0), (-50.0, -50.0, 950.0), (50.0, -50.0, 850.0)]
[/code]

Alternativ könnte man über eine generator-expression nachdenken, wenn die Daten (als Sequence) allzu umfangreich werden.
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Antworten