Hallo.
Ich bekomme aus einer Exec-Funktion Parameter geliefert.
Dies kann entweder ein String sein (nur ein Wert) oder ein Tuple (wenn mehrere Werte übergeben werden).
Ich habe keinen Einfluß darauf, ob ein String oder ein Tuple bei mir ankommt.
Nun sollen die erhaltenen Werte an eine Liste angehängt werden.
Bei String ist mir klar wie.
Aber was mache ich wenn ein Tuple kommt ?
if TUPLE .... ?
Oder gibt es was Integriertes ?
Danke für's Mitdenken.
MrNiceTry
String und Tuple unterscheiden, bzw. unterschiedlich auswert
MrNiceTry hat geschrieben:Nun sollen die erhaltenen Werte an eine Liste angehängt werden.
Bei String ist mir klar wie.
Aber was mache ich wenn ein Tuple kommt ?
Code: Alles auswählen
foo = [1]
bar = (2, 4, 8)
foo.extend(bar)
Ein Tuple kann man so erkennen:
Aber schön ist das nicht, weil du so keine Listen erkennst die du genauso verarbeiten könntest.
Andersrum hat man das Problem bei unicode/string.
Daher würde mich auch mal interessieren wie man das sauber unterscheiden kann.
Gruß
sparrow
Code: Alles auswählen
>>> a = (1, 2, 3)
>>> type(a) == type(())
True
>>>
Andersrum hat man das Problem bei unicode/string.
Daher würde mich auch mal interessieren wie man das sauber unterscheiden kann.
Gruß
sparrow
Hallo,
wenn man sowas überhaupt explizit überprüfen möchte, würde man mMn eher isinstance() nutzen:
Das geht dann auch für Tuple.
Besten Gruß,
brb
wenn man sowas überhaupt explizit überprüfen möchte, würde man mMn eher isinstance() nutzen:
Code: Alles auswählen
>>> isinstance([123,456], (list, tuple))
True
Besten Gruß,
brb
Supi, das ist eine tolle Lösung.Barabbas hat geschrieben:wenn man sowas überhaupt explizit überprüfen möchte, würde man mMn eher isinstance() nutzen:
Code: Alles auswählen
>>> isinstance([123,456], (list, tuple)) True
Wie wäre es denn für den Threadersteller ohne explizite Prüfung möglich sein Vorhaben umzusetzen?
Hallo,
die Frage habe ich mir auch gestellt. Wenn dir die Schnittstelle sowohl Strings als auch Tuples liefert, scheint nicht viel anderes übrig zu bleiben, als zu überprüfen, ob die jeweiligen Daten jetzt Strings oder Tuples sind.
Meine vorsichtige Formulierung bezog sich in diesem Fall also weniger darauf, dass ich eine bessere Lösung parat hätte, als darauf, dass ich betonen wollte, dass man nach Möglichkeit versucht, sowas zu vermeiden (Stichwort "Duck Typing"). Da Strings und Tuple aber letztlich jeweils Iterables sind, scheint mir dieser Ansatz in diesem Fall nicht sonderlich fruchtbar. Aber ich lasse mich da gerne belehren, ich mache mir ja auch nur meine Gedanken .
Besten Gruß,
brb
//edit: Nur um zu klären, wie ich das mit den Iterables meinte: Wenn man beispielsweise nicht zwischen Strings und Tuples, sondern zwischen Ints und Tuples unterscheiden müsste, könnte man statt eines expliziten Typ-Vergleichs folgendes machen:
Das wäre in so weit eine generischere Vorgehensweise, als dass alle Objekte, die __getitem__ oder __iter__ implementieren korrekt mit extend() in die Liste aufgenommen würden. Die Objekte, die diese Methoden nicht implementieren, würden aber zunächst einen TypeError werfen und dann ganz normal mit append() in die Liste aufgenommen werden.
Aber wie gesagt: Für den TE kommt diese Vorgehensweise so nicht in Frage, weil eben sowohl Strings als auch Tuples Iterables sind und somit über extend() aufgenommen werden. Die Strings dann aber Zeichen für Zeichen - was ja in diesem Fall nicht erwünscht sein dürfte.
die Frage habe ich mir auch gestellt. Wenn dir die Schnittstelle sowohl Strings als auch Tuples liefert, scheint nicht viel anderes übrig zu bleiben, als zu überprüfen, ob die jeweiligen Daten jetzt Strings oder Tuples sind.
Meine vorsichtige Formulierung bezog sich in diesem Fall also weniger darauf, dass ich eine bessere Lösung parat hätte, als darauf, dass ich betonen wollte, dass man nach Möglichkeit versucht, sowas zu vermeiden (Stichwort "Duck Typing"). Da Strings und Tuple aber letztlich jeweils Iterables sind, scheint mir dieser Ansatz in diesem Fall nicht sonderlich fruchtbar. Aber ich lasse mich da gerne belehren, ich mache mir ja auch nur meine Gedanken .
Besten Gruß,
brb
//edit: Nur um zu klären, wie ich das mit den Iterables meinte: Wenn man beispielsweise nicht zwischen Strings und Tuples, sondern zwischen Ints und Tuples unterscheiden müsste, könnte man statt eines expliziten Typ-Vergleichs folgendes machen:
Code: Alles auswählen
value = 3 #oder wahlweise ein Tuple wie (3, 5, )
data = []
try:
data.extend(value)
except TypeError:
data.append(value)
Aber wie gesagt: Für den TE kommt diese Vorgehensweise so nicht in Frage, weil eben sowohl Strings als auch Tuples Iterables sind und somit über extend() aufgenommen werden. Die Strings dann aber Zeichen für Zeichen - was ja in diesem Fall nicht erwünscht sein dürfte.
Zuletzt geändert von Barabbas am Donnerstag 17. Februar 2011, 12:07, insgesamt 1-mal geändert.
Ich könnte mir sowas vorstellen:
Code: Alles auswählen
output_list = []
output = #str or list
func = output_list.append if type(output) is str else output_list.extend
func(output)
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Was haben denn alle gegen isinstance? (bis auf Barabbas )
Wobei man sinnvoller Weise wohl eher auf "tuple" testen würde; eine Funktion liefert ja irgend ein Objekt, oder ein Tupel von Objekten.
Code: Alles auswählen
func = output_list.append if isinstance(output, str) else output_list.extend
func(output)
Zuletzt geändert von Hyperion am Donnerstag 17. Februar 2011, 12:15, insgesamt 1-mal geändert.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ich würde auch sagen, dass die API an der Stelle einfach unschön ist. Um das "duck typing" möglichst wenig zu beeinträchtigen würde ich übrigens auf die Zeichenkette prüfen und nicht auf das Tupel. In der Praxis "erfinden" die Leute nämlich eher eigene, iterierbare Containertypen statt Zeichenketten abzuleiten. Ungetestet:
@mutetella: Wenn schon dann gleich komplett in einer Zeile und ohne Namen zu wiederholen:
Code: Alles auswählen
if isinstance(param, basestring):
data.append(param)
else:
data.extend(param)
Code: Alles auswählen
getattr(data, 'append' if isinstance(param, basestring) else 'extend')(param)
@BlackJack: Das ist cool, auf sowas steh' ich...
Danke!
Und isinstance() ist natürlich auch schöner als type(). Wenn man über Typprüfung nachdenkt, dann drängt sich halt dieses 'type' auf...
mutetella
Danke!
Und isinstance() ist natürlich auch schöner als type(). Wenn man über Typprüfung nachdenkt, dann drängt sich halt dieses 'type' auf...
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
Das ist meiner Meinung nach tatsächlich der einzig sinnvolle Weg.BlackJack hat geschrieben:Ich würde auch sagen, dass die API an der Stelle einfach unschön ist. Um das "duck typing" möglichst wenig zu beeinträchtigen würde ich übrigens auf die Zeichenkette prüfen und nicht auf das Tupel. In der Praxis "erfinden" die Leute nämlich eher eigene, iterierbare Containertypen statt Zeichenketten abzuleiten.
Hat man etwas, das entweder ein () oder ein [] ist, und man will testen, was was ist, ohne isinstance zu benutzen (was der naheliegende Weg wäre) fällt mir folgendes ein:
Stefan
Code: Alles auswählen
def is_tuple(x):
try:
() + x
return True
except TypeError:
return False
def is_list(x):
try:
[] + x
return True
except TypeError:
return False