Hallo Leute,
bei meinem Vorhaben den String "a[n][n]" irgendwie zu einem Variablennamen hinzubiegen, ist es mir schon gestern Nacht kalt den Rücken runter gelaufen, aber ich wußte keinen Rat mehr. EyDu hat Recht, denn ein guter Code sollte soetwas nicht brauchen. Meine grundsätzliche Frage ist auch gelöst, aber es gibt da noch eine andere Frage. Hier aber erstmal worum es mir ging:
Ich habe einen String, zum Beispiel str_="(1, 2.2), 3.3, (4.4, ((5.5, 6), 7))", den ich anschließend mit eval(String) in ein Tuple mit Untertuples umwandel. Meine grundsätzliche Frage war: Wie kriege ich hin abzufragen, ob es beispielsweise ein tuple_[0][0] gibt, ohne einen Error zu riskieren? Die Anwort darauf ist recht einfach über diese Funktion (danke@ maxx 981):
Code: Alles auswählen
def getVal(li,indizes):
try:
val = li
for lind in indizes:
val = val[lind]
return val
except TypeError:
return None
def main():
str_ = "(1, 2.2), 3.3, (4.4, ((5.5, 6), 7))"
tuple_ = eval(str_)
print getVal(tuple_,[0,1]) #Output: 2.2
print getVal(tuple_,[1,0]) #Output: None
Mein Hirnknotenansatz war aber der: Ich lasse mir zuerst alle Inhalts-Indendifikationsmöglichkeiten in eine Liste ausgeben. Für das Beispiel sähe das so aus:
Code: Alles auswählen
print list_ #Output: [(0,0),(0,1),1,(2,0),(2,1,0,0),(2,1,0,1),(2,1,1)]
Diese Liste habe ich über eine Reihe von Schleifen versucht zu lösen.
Code: Alles auswählen
list_=[]
if isinstance(tuple_, tuple) == True:
for i in range(len(tuple_)):
if isinstance(tuple_[i], tuple) == True:
for ii in range(len(tuple_[i])):
if isinstance(tuple_[i][ii], tuple) == True:
for iii in range(len(tuple_[i][ii])):
if isinstance(tuple_[i][ii][iii], tuple) == True:
for iiii in range(len(tuple_[i][ii][iii])):
if isinstance(tuple_[i][ii][iii][iiii], tuple) == True:
for iiiii in range(len(tuple_[i][ii][iii][iiii])):
if isinstance(tuple_[iiiii], tuple) == True:
print "Irgendwie nimmt das kein Ende!"
else: list_.append((i, ii, iii, iiii, iiiii))
else: list_.append((i, ii, iii, iiii))
else: list_.append((i, ii, iii))
else: list_.append((i, ii))
else: list_.append((i))
else: print "kein tuple"
Diese Weise erscheint mir sehr unelegant. Unelegant ist nachfolgend auch die Funktion, wie ich dann abfrage ob es ein tuple[n][n] gibt.
Code: Alles auswählen
def GetElement(t, l, n):
if (n) in l:
if isinstance(n,int) == True: return t[n]
if len(n) == 2: return t[n[0]][n[1]]
if len(n) == 3: return t[n[0]][n[1]][n[2]]
if len(n) == 4: return t[n[0]][n[1]][n[2]][n[3]]
else: return False
Output:
Code: Alles auswählen
#str_ = "(1, 2.2), 3.3, (4.4, ((5.5, 6), 7))"
print list_ #Output: [(0,0),(0,1),1,(2,0),(2,1,0,0),(2,1,0,1),(2,1,1)]
print GetElement(tuple_,list_,(1)) #Output: 3.3
print GetElement(tuple_,list_,(1,0)) #Output: False
print GetElement(tuple_,list_,(2,1,0,0)) #Output: 5.5
print GetElement(tuple_,list_,(2,1,0,1)) #Output: 6
Und nun wollte ich es hinkriegen die Zeilen in GetElement zu reduzieren und meinte es irgendwie über Mach-String-zu-Variablennamen hinbiegen zu können. Asche auf mein Haupt, das war dumm. Allerdings hätte ich trotzdem gerne eine Auflistung aller Inhalts-Indendifikationsmöglichkeiten. Problem an der Schleifenvariante, wie ich sie geschrieben habe ist, dass sie extrem lang ist und dabei gerade mal bis in die 4. Ebene kommt. Gibt es da nicht eine viel viel elegantere Möglichkeit?
Wenn jemand einen Tipp hat wäre ich sehr dankbar.
@ jerch und Hyperion: Darf ich nachfragen was es mit eval==evil und LISP ist tot auf sich hat?
Viele Grüße
Rown