Seite 1 von 1

String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 01:38
von rown
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

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 02:05
von EyDu
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

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 03:47
von jerch
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?

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 11:32
von Hyperion
jerch hat geschrieben:(und LISP ist tot - Ruhe in Frieden.... :shock: )
Oha... das kann Ärger geben... :-D

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 13:08
von rown
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

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 15:59
von 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()

Re: String in Variable konvertieren?

Verfasst: Mittwoch 11. Januar 2012, 17:47
von rown
Es gibt viel zu verstehen!

vielen vielen vielen Dank
Rown