String in Variable konvertieren?

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
rown
User
Beiträge: 7
Registriert: Mittwoch 11. Januar 2012, 01:23

Hallo an alle,

ich arbeite erst sehr kurze Zeit mit Python in Cinema4d und glaube bei manchen Fragen auf einer Python-Plattform besser aufgehoben zu sein als im c4d-Forum. Meine Frage ist:

Code: Alles auswählen

#Welcome to the world of Python
def main():
    a = ((1,2,3),(3,4))
    n = 0
    print a                #Output: ((1,2,3),(3,4))
    print a[0][0]          #Output: 1
    print convert"a[n][n]" #Wie kriege ich es hin, dass der Output hier auch 1 ist?
kann man einen String in einen Variablennamen konvertieren?

Vielen Dank und viele Grüße
Rown
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Aus deinem Beispiel wird nicht so richtig deutlich, was du eigentlich vor hast. Natürlich könnte man einen String auswerten, das bringt aber zu viele Nachteile mit sich, als dass man dies tatsächlich machen wollen würde. Welches konkrete Problem hast du denn, welches du Lösen möchtest? Hier gibt es mit Sicherheit eine bessere und saubere Lösung.

Sebastian
Das Leben ist wie ein Tennisball.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

eval ist Dein Freund :lol: :

Code: Alles auswählen

>>> a = ((1,2,3),(3,4))
>>> n = 0
>>> print a
((1, 2, 3), (3, 4))
>>> print a[0][0]
1
>>> print eval('a[n][n]')
1
ABER: eval == evil, böse .... :twisted: (und LISP ist tot - Ruhe in Frieden.... :shock: )

Im Ernst, sauberer Code braucht sowas nicht. Daher, EyDu wiederholend, was ist Dein Ziel?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

jerch hat geschrieben:(und LISP ist tot - Ruhe in Frieden.... :shock: )
Oha... das kann Ärger geben... :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
rown
User
Beiträge: 7
Registriert: Mittwoch 11. Januar 2012, 01:23

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
BlackJack

@rown: „`eval()` == evil” bedeutet das `eval()` böse ist, und nicht verwendet werden sollte. Es ist ein Sicherheitsloch und oft auch gar nicht nötig. In diesem Fall würde zum Beispiel `ast.literal_eval()` wohl ausreichen:

Code: Alles auswählen

In [121]: ast.literal_eval('(1, 2.2), 3.3, (4.4, ((5.5, 6), 7))')
Out[121]: 
((1, 2.2000000000000002),
 3.2999999999999998,
 (4.4000000000000004, ((5.5, 6), 7)))
Warum LISP tot sein soll verstehen ich auch nicht. Kann man das überhaupt töten!? Also ohne signifikanten Schaden am Zusammenhalt des Universums anzurichten!? :-D

Du hast eine rekursive Datenstruktur — also bietet sich auch ein rekursiver Algorithmus an:

Code: Alles auswählen

def iter_paths(data, path=()):
    for i, sub_data in enumerate(data):
        sub_path = path + (i,)
        if isinstance(sub_data, tuple):
            for result in iter_paths(sub_data, sub_path):
                yield result
        else:
            yield sub_path


def main():
    data = ((1, 2.2), 3.3, (4.4, ((5.5, 6), 7)))
    print list(iter_paths(data))


if __name__ == '__main__':
    main()
rown
User
Beiträge: 7
Registriert: Mittwoch 11. Januar 2012, 01:23

Es gibt viel zu verstehen!

vielen vielen vielen Dank
Rown
Antworten