Seite 1 von 1
Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 15:51
von BubiDu
Hallo zusammen,
vorab, wenn ich im falschen Forum poste, sagt bescheid, dann verschiebe ich den Post.
Nun zu meinem Problem. Ich bin im Moment dabei, einen Ableitungs-Rechner zu erstellen. Die Funktion wird dabei in verschachtelten Listen aufbewahrt. Lasse ich die Funktion expAbleiten auf eine Liste los, so verändert sich ein Wert, der gar nicht angesprochen wird. Hier der Code:
Code: Alles auswählen
def grfAbleiten(Summand, var0int): #var0int=Variable of Interest.
end=len(Summand[2]) #how many variables to check?
for i in range (0,end,1): #which variable is asked for?
if(var0int==Summand[2][i]):
var0int=i #change var0int to list number
Ableitung=Summand
Ableitung[1]=int(Ableitung[3][var0int])*int(Ableitung[1])#actual derivation
print(Summand)
Ableitung[3][var0int]=int(Ableitung[3][var0int])-1 #actual derivation
print(Summand)
##print(Ableitung)
return(Ableitung)
def expAbleiten(Summand, var0int):
nachDif=grfAbleiten(Summand[1:],var0int) #Bisher nur für grfAbleitung
Ableitung=[5,nachDif,Summand] #Kettenregel der Ableitung
return Ableitung
Folgendes gibt mir die Shell als Resultat:
>>> expAbleiten([2,4,5,["a","b"],[6,7,]],"a")
[4, 30, ['a', 'b'], [6, 7]]
[4, 30, ['a', 'b'], [5, 7]]
[5, [4, 30, ['a', 'b'], [5, 7]], [2, 4, 5, ['a', 'b'], [5, 7]]]
Das vorletzte Element im Ergebnis, also die Fünf in Liste[2][2][1] müsste eine Sechs sein. Seltsam ist, dass die Änderung eindeutig während der Ausführung der Fkt. grfAbleiten auftritt, was schon mal gar nicht sein kann. Findet jemand meinen Fehler? Oder gibt es ein bekanntes Problem mit zu verschachtelten Listen?
Vielen Dank im Vorraus!
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 16:06
von BlackJack
@BubiDu: Du veränderst vorhandene Listen und dadurch, äh ja naja, verändern die sich halt. Eventuell hast Du von Parameterübergaben und von Zeile 6 eine falsche Vorstellung: Bei beiden wird nichts kopiert, es wird bloss vorhandenen Objekten ein (zusätzlicher) Name gegeben.
Am besten erstellst Du in Funktionen neue Listen und veränderst keine. Nur dann verhält sich das wie man das von Funktionen erwartet.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 16:41
von BubiDu
@BlackJack: Erstenmal vielen Dank für die schnelle Antwort, aber ich fürchte so ganz verstanden Habe ich das Problem nicht. In Zeile sechs Dupliziere ich ja meine Liste namens "Summand". Die anschließenden Operationen dürften doch nur noch die neue Liste "Ableitung" Betreffen oder? Man beachte, dass die beiden "Prints" zwischendrin den "Summanden" ausgeben sollten, nicht die "Ableitung". Trotzdem ist eine Änderung zu sehen. Wenn der Fehler dennoch bei mir liegt, könntest du mir das noch einmal erklären?
Edit: Ich glaube mir ist gerade doch aufgegangen, was du sagen möchtest, jedoch verstehe ich dann nicht, warum die Operation in Zeile 9 ohne Konsequenzen für die Endausgabe bleibt. Gibt es eine möglichkeit, solche Objekte wirklich zu duplizieren, anstatt nur einen zweiten Namen zu erstellen?
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 17:04
von BlackJack
@BubiDu: Zeile 9 hat doch einen Effekt.
Ja es gibt eine Möglichkeit die Datenstruktur zu kopieren, aber das ist nicht der Weg den man gehen würde. Man würde eine neue Liste erstellen und die Sachen die nicht verändert werden einfach übernehmen und die Sachen die verändert werden neu und verändert erstellen.
Mir ist die Listenstruktur übrigens nicht so ganz klar. Die ”riecht” komisch denn normalerweise speichert man in Listen gleichartige Elemente, da sind aber in der äusseren Liste Zahlen und Listen als Elemente. Das ist eigenartig und wahrscheinlich nicht der beste Weg die Daten zu repräsentieren.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 17:23
von BubiDu
@BlackJack: Dann werde ich mich da mal dran versuchen. Vielen Dank noch einmal, das Problem habe ich auf jeden Fall verstanden, wie ich es lösen werde überlege ich mir noch.
Ja, ich verstehe, dass dir meine Datenstruktur sehr seltsam vorkommt, aber ich wage zu behaupten, dass sie eine recht geschickte Lösung meines Problems ist. Ersichtlich wird das mit dem Rest des Codes. Im Grunde repräsentiert jede Stelle in der Liste einen definierten Teil einer Funktion.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 17:29
von /me
BubiDu hat geschrieben:Gibt es eine möglichkeit, solche Objekte wirklich zu duplizieren, anstatt nur einen zweiten Namen zu erstellen?
Für ein Duplikat über mehrere Ebenen bietet sich
deepcopy an.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 17:33
von BlackJack
@BubiDu: Das die Liste die Funktion repräsentiert ist schon klar, aber *wie*!? Ich habe da so ein bisschen den Verdacht das da nach ”falschen” Kriterien sortiert wurde, also eigentlich zusammengehörige Information in getrennten Listen gespeichert werden. Was die ganze Sache eher komplizierter als einfacher machen würde.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 19:44
von Sirius3
@BubiDu: irgendwie habe ich das Gefühl, als ob die Listen eigentlich Objekte sind, bei denen die Position der Elemente eine bestimmte Bedeutung hat. Zusätzlich gibt es noch jede Menge magischer Werte: Was bedeutet denn die 5 in Zeile 16? Gerade Ableitungen sind ja ein schönes Beispiel, um mit Objektorientierter Programmierung anzufangen.
Wenn der Variablenname in einem Kommentar erkärt werden muss, ist das ein deutliches Zeichen dafür, dass man einen besseren Namen suchen sollte.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Dienstag 21. April 2015, 20:08
von BlackJack
@BubiDu: Wenn wir gerade dabei sind über magische Indexwerte zu sprechen, kann es sein das der feste Indexwert 1 in Zeile 7 eigentlich von der Variablen abhängen sollte? Oder ich habe diese Struktur immer noch nicht verstanden.
Edit: Ach so, vielleicht sollte man an der Stelle auch `sympy` erwähnen.

Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Mittwoch 22. April 2015, 10:53
von BlackJack
@BubiDu: Wie gesagt ich verstehe nicht wirklich was Deine Listen bedeuten, also bin ich hier ein wenig auf Spekulation angewiesen. So würde ich die Daten organisieren wenn man Summanden die aus einem Koeffizienten, einem Variablennamen, und einem Exponenten bestehen ableiten müsste (und aus unerfindlichen Gründen Klassen verboten wären):
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
from collections import namedtuple
Exponent = namedtuple('Exponent', 'coefficient variable_name exponent')
def exponent2str(exponent):
result = list()
if exponent.coefficient != 1:
result.append(str(exponent.coefficient))
if exponent.coefficient != 0 and exponent.exponent != 0:
if result:
result.append('*')
result.append(exponent.variable_name)
if exponent.exponent != 1:
result.append('^{0}'.format(exponent.exponent))
return ''.join(result)
def diff_exponent(exponent, variable_name):
if exponent.variable_name == variable_name and exponent.exponent != 0:
return Exponent(
exponent.coefficient * exponent.exponent,
exponent.variable_name,
exponent.exponent - 1
)
else:
return None
def sum2str(exponents):
return ' + '.join(exponent2str(e) for e in exponents)
def diff_sum(exponents, variable_name):
result = list()
for exponent in exponents:
diff = diff_exponent(exponent, variable_name)
if diff is not None:
result.append(diff)
return result
def main():
summands = [
Exponent(1, 'a', 42), Exponent(2, 'b', 23), Exponent(3, 'a', 4711),
Exponent(4, 'a', 2), Exponent(5, 'a', 1), Exponent(6, 'a', 0),
]
print(sum2str(summands))
print(sum2str(diff_sum(summands, 'a')))
if __name__ == '__main__':
main()
Ausgabe:
Code: Alles auswählen
a^42 + 2*b^23 + 3*a^4711 + 4*a^2 + 5*a + 6
42*a^41 + 14133*a^4710 + 8*a + 5
Aber eigentlich würde ich auch das schon mit Klassen umsetzen wollen.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Mittwoch 22. April 2015, 20:22
von BubiDu
Also abschließend: Ja es gibt magische Positionen, wie es in einem vorherigen Post genannt wurde. Und ja, es mag etwas wirr und undurchsichtig wirken, aber es repräsentiert meine Denkstrukturen sehr gut, außerdem wird es wie gesagt durchsichtiger, wenn man den gesamten Code vor sich hat. Es mag nicht die schönste Lösung und nicht die feine englische Art sein (sogar wortwörtlich, auf deutsch coden schickt sich ja bekanntlich nicht

) aber für mich ist sie brauchbar. Habe ich die Kiste prinzipiell am laufen, lässt sich sicher über Verbesserungspotential reden, weil garantiert eine Menge davon da ist, aber ich bin Chemiker und kein Programmierer, insofern schwankt meine Motivation diesbezüglich sehr. Es ist für mich eben nur eine "Spielerei".
Trotzdem vielen vielen Dank für all eure Mühe, das schätze ich sehr.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Mittwoch 22. April 2015, 21:41
von BlackJack
@BubiDu: Deine Denkstrukturen sind also wirr und undurchsichtig‽

Ich weiss nicht ob ich bei Daten in Listen wo Indexpositionen bestimmte Bedeutungen haben noch als ”Verbesserungspotential” bezeichnen würde. Das klingt arg euphemistisch. Als ob wenn es jetzt gut wäre und man es halt noch ein bisschen verbessern könnte. Bei Quelltexten wo man nicht einzelne Funktionen nachvollziehen kann ohne das gesamte Programm zu kennen hat man sehr schnell zu viel damit zu tun den Überblick zu bewahren. Das geht eine zeitlang gut, insbesondere solange man es selber *gerade aktuell* schreibt, aber wenn man nach einiger Zeit solchen Code wieder anschaut bekommt man selbst die Probleme die jetzt schon andere damit haben, denn nach einem halben Jahr ist man üblicherweise selber der Fremde der den eigenen Quelltext wieder neu erarbeiten muss.
Re: Hilfe bei Problem mit verschachtelten Listen
Verfasst: Samstag 25. April 2015, 18:18
von BlackJack
Ich konnt's mir nicht verkneifen das mit Klassen umzuschreiben und einen kleinen ”Parser” für die Zeichenkettendarstellung einzubauen:
Code: Alles auswählen
#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import re
class Exponent(object):
RE = re.compile(
r'\s*((?P<coeff>-?\d+)\s*\*?\s*)?'
r'(?P<var>[a-z])?\s*'
r'(\^(?P<exp>-?\d+))?\s*'
)
def __init__(self, coefficient, variable_name, exponent):
self.coefficient = coefficient
self.variable_name = variable_name
self.exponent = exponent
def __str__(self):
result = list()
if self.coefficient != 1:
result.append(str(self.coefficient))
if self.coefficient != 0 and self.exponent != 0:
if result:
result.append('*')
result.append(self.variable_name)
if self.exponent != 1:
result.append('^{0}'.format(self.exponent))
return ''.join(result)
def diff(self, variable_name):
if self.variable_name == variable_name and self.exponent != 0:
return Exponent(
self.coefficient * self.exponent,
self.variable_name,
self.exponent - 1
)
else:
return None
@classmethod
def from_string(cls, string):
match = cls.RE.match(string)
coefficient = int(match.group('coeff') or 1)
variable_name = match.group('var') or ''
exponent = int(match.group('exp') or (1 if variable_name else 0))
return cls(coefficient, variable_name, exponent)
class Sum(object):
def __init__(self, summands):
self.summands = summands
def __iter__(self):
return iter(self.summands)
def __str__(self):
return ' + '.join(str(summand) for summand in self)
def diff(self, variable_name):
result = list()
for summand in self:
diff = summand.diff(variable_name)
if diff is not None:
result.append(diff)
return Sum(result)
@classmethod
def from_string(cls, string):
return cls(map(Exponent.from_string, string.split('+')))
def main():
summands = Sum.from_string('a^42 + 2*b^23 + 3*a^4711 + 4*a^2 + 5*a + 6')
assert str(summands) == str(Sum.from_string(str(summands)))
print(summands)
print(summands.diff('a'))
if __name__ == '__main__':
main()