Wie überprüfe ich, ob ein Objekt eine Liste oder ein Tupel ist (aber keine Zeichenfolge)?

443

Dies ist, was ich normalerweise mache, um sicherzustellen, dass die Eingabe a list/ tuple- aber nicht a ist str. Weil ich oft auf Fehler gestoßen bin, bei denen eine Funktion versehentlich ein strObjekt passiert , und die Zielfunktion for x in lstdavon ausgeht, dass lstes sich tatsächlich um ein listoder handelt tuple.

assert isinstance(lst, (list, tuple))

Meine Frage ist: Gibt es einen besseren Weg, dies zu erreichen?

Sridhar Ratnakumar
quelle
9
Typ (lst) ist Liste?
Jackalope
1
nicht isinstance (key, six.string_types)
wyx

Antworten:

332

Nur in Python 2 (nicht in Python 3):

assert not isinstance(lst, basestring)

Ist eigentlich das, was Sie wollen, sonst verpassen Sie viele Dinge, die sich wie Listen verhalten, aber keine Unterklassen von listoder sind tuple.

Nick Craig-Wood
quelle
91
Ja, das ist die richtige Antwort. In Python 3 basestringist weg, und Sie suchen nur nach isinstance(lst, str).
Steveha
5
Es gibt viele Dinge, die Sie iterieren können, wie Listen, z. B. setGeneratorausdrücke, Iteratoren. Es gibt exotische Dinge wie mmapweniger exotische Dinge, arraydie sich wie Listen verhalten, und wahrscheinlich noch viel mehr, das ich vergessen habe.
Nick Craig-Wood
50
Es ist erwähnenswert, dass dies nicht garantiert, dass lstes iterierbar ist, während das Original dies tat (z. B. ein Int würde diese Prüfung bestehen)
Peter Gibson
11
@PeterGibson - Eine Kombination aus beiden bietet eine gültige, restriktivere Prüfung und stellt sicher, dass 1) lst iterierbar ist, 2) lst keine Zeichenfolge ist. assert isinstance(lst, (list, tuple)) and assert not isinstance(lst, basestring)
strongMA
4
Nun, diese Lösung sucht nur nach von Zeichenfolgen abgeleiteten Typen, aber was ist mit Ganzzahlen, Doppelwerten oder anderen nicht iterierbaren Typen?
Eneko Alonso
171

Denken Sie daran, dass wir in Python "Duck Typing" verwenden möchten. Alles, was sich wie eine Liste verhält, kann als Liste behandelt werden. Überprüfen Sie also nicht den Typ einer Liste, sondern prüfen Sie, ob sie sich wie eine Liste verhält.

Aber Strings wirken auch wie eine Liste, und oft ist das nicht das, was wir wollen. Es gibt Zeiten, in denen es sogar ein Problem ist! Suchen Sie also explizit nach einer Zeichenfolge, verwenden Sie dann jedoch die Ententypisierung.

Hier ist eine Funktion, die ich zum Spaß geschrieben habe. Es ist eine spezielle Version repr(), die jede Sequenz in spitzen Klammern ('<', '>') druckt.

def srepr(arg):
    if isinstance(arg, basestring): # Python 3: isinstance(arg, str)
        return repr(arg)
    try:
        return '<' + ", ".join(srepr(x) for x in arg) + '>'
    except TypeError: # catch when for loop fails
        return repr(arg) # not a sequence so just return repr

Dies ist insgesamt sauber und elegant. Aber was macht dieser isinstance()Scheck dort? Das ist eine Art Hack. Aber es ist wichtig.

Diese Funktion ruft sich rekursiv für alles auf, was sich wie eine Liste verhält. Wenn wir die Zeichenfolge nicht speziell behandeln würden, würde sie wie eine Liste behandelt und jeweils ein Zeichen aufgeteilt. Aber dann würde der rekursive Aufruf versuchen, jedes Zeichen als Liste zu behandeln - und es würde funktionieren! Sogar eine einstellige Zeichenfolge funktioniert als Liste! Die Funktion ruft sich selbst rekursiv auf, bis der Stapel überläuft.

Funktionen wie diese, die von jedem rekursiven Aufruf abhängen, der die zu erledigende Arbeit aufschlüsselt, müssen Sonderzeichenfolgen enthalten - da Sie eine Zeichenfolge nicht unter der Ebene einer Zeichenfolge mit einem Zeichen und sogar einer Zeichenfolge aufteilen können -character string verhält sich wie eine Liste.

Hinweis: Das try/ exceptist der sauberste Weg, um unsere Absichten auszudrücken. Wenn dieser Code jedoch zeitkritisch wäre, möchten wir ihn möglicherweise durch eine Art Test ersetzen, um festzustellen, ob arges sich um eine Sequenz handelt. Anstatt den Typ zu testen, sollten wir wahrscheinlich das Verhalten testen. Wenn es eine .strip()Methode hat, ist es eine Zeichenfolge. Betrachten Sie sie also nicht als Sequenz. Andernfalls ist es eine Sequenz, wenn es indizierbar oder iterierbar ist:

def is_sequence(arg):
    return (not hasattr(arg, "strip") and
            hasattr(arg, "__getitem__") or
            hasattr(arg, "__iter__"))

def srepr(arg):
    if is_sequence(arg):
        return '<' + ", ".join(srepr(x) for x in arg) + '>'
    return repr(arg)

BEARBEITEN: Ich habe das Obige ursprünglich mit einem Check für geschrieben, __getslice__()aber ich habe festgestellt, dass in der collectionsModuldokumentation die interessante Methode ist __getitem__(); Das macht Sinn, so indizieren Sie ein Objekt. Das scheint grundlegender zu sein, __getslice__()also habe ich das oben Gesagte geändert.

steveha
quelle
2
@stantonk, danke, dass Sie das gesagt haben, aber ich denke, dass es bereits eine akzeptierte Antwort gab, als ich dies schrieb, und ich erwarte nicht wirklich, dass die akzeptierte Antwort geändert wird.
Steveha
@steveha: sreprist eine sehr interessante Idee. Aber ich bin anderer Meinung als Sie, ob es sich um einen Sonderfall handelt str. Ja, strist bei weitem die offensichtlichste und häufigste iterable, die eine unendliche Rekursion in verursachen würde srepr. Aber ich kann mir leicht benutzerdefinierte Iterables vorstellen, die sich gleich verhalten (mit oder ohne guten Grund). Anstelle eines Sonderfalls strsollten wir zugeben, dass dieser Ansatz in eine unendliche Rekursion geraten kann, und einer Art und Weise zustimmen, wie wir damit umgehen. Ich werde meinen Vorschlag in einer Antwort veröffentlichen.
Max
1
Ich denke, das ist definitiv der richtige Weg. Um den Sonderfall (der Zeichenfolge in diesem Szenario) zu behandeln, sollten wir jedoch besser die Frage stellen: "Wie würde ein Mensch den Unterschied erkennen?" Stellen Sie sich beispielsweise ein Funktionsargument vor, das eine Liste von E-Mail-Adressen oder eine einzelne E-Mail-Adresse sein kann (wobei zu beachten ist, dass eine Zeichenfolge einfach eine Liste von Zeichen ist). Geben Sie diese Variable einem Menschen. Wie konnte das sagen was es ist? Der einfachste Weg, den ich mir vorstellen kann, ist zu sehen, wie viele Zeichen sich in jedem Element der Liste befinden. Wenn es größer als 1 ist, kann das Argument sicherlich keine Liste von Zeichen sein.
Josh
1
Ich habe ein bisschen darüber nachgedacht und es mit ein paar anderen Leuten besprochen, und ich denke, es srepr()ist in Ordnung, wie es ist. Wir brauchen eine rekursive Funktion, um Dinge wie eine Liste zu behandeln, die in einer anderen Liste verschachtelt ist. aber für Zeichenketten würden wir sie lieber als "foo"als drucken lassen <'f', 'o', 'o'>. Eine explizite Prüfung auf einen String ist hier also sinnvoll. Es gibt auch keine anderen Beispiele für Datentypen, bei denen das Iterieren immer eine Iterierbarkeit zurückgibt und die Rekursion immer einen Stapelüberlauf verursacht. Daher benötigen wir keine spezielle Eigenschaft, um dies zu testen ("Praktikabilität schlägt Reinheit").
Steveha
1
Dies funktioniert nicht in Python 3, da Strings eine __iter__()Methode in Python 3 haben, aber nicht in Python 2. Sie vermissen Klammern in is_sequence(), es sollte lauten:return (not hasattr(arg, "strip") and (hasattr(arg, "__getitem__") or hasattr(arg, "__iter__")))
MiniQuark
124
H = "Hello"

if type(H) is list or type(H) is tuple:
    ## Do Something.
else
    ## Do Something.
Mani Shankar Venkankatachalam
quelle
11
Es wird jedoch nicht die Python-Sprache der Ententypisierung verwendet, wie andere Kommentatoren hervorgehoben haben (obwohl die Frage direkt und sauber beantwortet wird).
Soren Bjornstad
7
Diese Antwort ist weniger akzeptabel als andere, da sie keine Ententypisierung zulässt und auch im einfachen Fall der Unterklasse fehlschlägt (ein typisches Beispiel ist die namedtuple-Klasse).
Philippe Gauthier
11
"Ententipp nicht zulassen" macht die Antwort nicht weniger akzeptabel, insbesondere angesichts der Tatsache, dass diese Antwort die Frage tatsächlich beantwortet.
Petri
4
Ich habe diese Antwort positiv bewertet, sie if isinstance( H, (list, tuple) ): ...ist jedoch kürzer und klarer.
shahar_m
2
Alternative Syntax:if type(H) in [list, tuple]:
Štefan Schindler
77

Für Python 3:

import collections.abc

if isinstance(obj, collections.abc.Sequence) and not isinstance(obj, str):
    print("obj is a sequence (list, tuple, etc) but not a string")

In Version 3.3 geändert: Abstrakte Basisklassen für Sammlungen in das Modul collection.abc verschoben. Aus Gründen der Abwärtskompatibilität sind sie auch in diesem Modul bis zur Version 3.8 sichtbar, in der sie nicht mehr funktionieren.

Für Python 2:

import collections

if isinstance(obj, collections.Sequence) and not isinstance(obj, basestring):
    print "obj is a sequence (list, tuple, etc) but not a string or unicode"
suzanshakya
quelle
5
Beeindruckend! Das funktioniert wirklich gut und ist viel prägnanter als jede andere richtige Antwort. Ich hatte keine Ahnung, von welchen die eingebauten Typen erben, collections.Sequenceaber ich habe es getestet und sehe, dass sie es tun. Das tut es auch xrange. Noch besser ist, dass dieser Test ausschließt dict, der sowohl __getitem__als auch hat __iter__.
Neil Mayhew
Irgendeine Idee, warum das Ergebnis von inspect.getmro(list)nicht enthält Sequence? Wie sollen wir herausfinden, was wir tun können, isinstancewenn getmronicht alles gezeigt wird?
Steve Jorgensen
@SteveJorgensen Method Resolution Order definiert den Klassensuchpfad, der von Python verwendet wird, um nach der richtigen Methode für Klassen zu suchen. Sequenceist eine abstrakte Klasse.
Suzanshakya
3
In Python3 können Sie isinstance (obj, basestring) durch isinstance (obj, str) ersetzen, und das sollte funktionieren.
Adrian Keister
2
in Python 3 brauchen und nicht isinstance (obj, bytes) ... wenn Sie eine Liste von Dingen wollen und nicht nur Bytes aufzählen wollen ...
Erik Aronesty
35

Python mit PHP-Geschmack:

def is_array(var):
    return isinstance(var, (list, tuple))
Cesar
quelle
6
Python ist eine Sprache vom Typ Ente, daher sollten Sie wirklich prüfen, ob var ein Attribut hat __getitem__. Auch der Name ist irreführend, da es auch ein Array-Modul gibt. Und die var könnte auch eine numpy.ndarray oder ein anderer Typ sein, der hat __getitem__. Die richtige Antwort finden Sie unter stackoverflow.com/a/1835259/470560 .
Peterhil
9
@ Peterhil strhat auch __getitem__deshalb Ihren Scheck nicht ausschließenstr
erikbwork
9
Ein Diktat auch. Nach zu suchen __getitem__ist hier ein schlechter Rat.
Petri
10

Im Allgemeinen ist die Tatsache, dass eine Funktion, die über ein Objekt iteriert, sowohl für Zeichenfolgen als auch für Tupel und Listen funktioniert, mehr eine Funktion als ein Fehler. Sie sicherlich können verwenden isinstanceoder Ente eingeben ein Argument zu überprüfen, aber warum sollten Sie?

Das klingt nach einer rhetorischen Frage, ist es aber nicht. Die Antwort auf "Warum sollte ich den Typ des Arguments überprüfen?" wird wahrscheinlich eine Lösung für das eigentliche Problem vorschlagen, nicht für das wahrgenommene Problem. Warum ist es ein Fehler, wenn eine Zeichenfolge an die Funktion übergeben wird? Außerdem: Wenn es ein Fehler ist, wenn eine Zeichenfolge an diese Funktion übergeben wird, ist es auch ein Fehler, wenn eine andere iterierbare Nicht-Liste / Tupel an diese Funktion übergeben wird? Warum oder warum nicht?

Ich denke, dass die häufigste Antwort auf die Frage wahrscheinlich ist, dass Entwickler, die schreiben, f("abc")erwarten , dass sich die Funktion so verhält, als hätten sie geschrieben f(["abc"]). Es gibt wahrscheinlich Umstände, in denen es sinnvoller ist, Entwickler vor sich selbst zu schützen, als den Anwendungsfall des Iterierens über die Zeichen in einer Zeichenfolge zu unterstützen. Aber ich würde zuerst lange und gründlich darüber nachdenken.

Robert Rossney
quelle
16
"Aber ich würde zuerst lange und gründlich darüber nachdenken." Ich würde nicht. Wird die Funktion sein soll eine Liste-y - Funktion, dann ja, es sollte ihnen die gleiche Behandlung (dh eine Liste gegeben, spucken es nach hinten aus, Dinge wie das). Wenn es sich jedoch um eine Funktion handelt, bei der eines der Argumente entweder eine Zeichenfolge oder eine Liste von Zeichenfolgen sein kann (was häufig vorkommt), scheint es ein bisschen viel zu sein , den Entwickler zu zwingen, diese Funktion immer innerhalb eines Arrays einzugeben . Denken Sie auch darüber nach, wie Sie beispielsweise mit JSON-Eingaben umgehen würden. Sie möchten auf jeden Fall eine Liste von Objekten behandeln, die sich von einer Zeichenfolge unterscheiden.
Jordan Reiter
8

Versuchen Sie dies für die Lesbarkeit und Best Practices:

Python2

import types
if isinstance(lst, types.ListType) or isinstance(lst, types.TupleType):
    # Do something

Python3

import typing
if isinstance(lst, typing.List) or isinstance(lst, typing.Tuple):
    # Do something

Ich hoffe es hilft.

Om Prakash
quelle
Python 3.6.5:AttributeError: module 'types' has no attribute 'ListType'
Juha Untinen
1
In Python 3 ist es: from typing import List-> isinstance([1, 2, 3], List= Trueund isinstance("asd", List)= False
Juha Untinen
5

Das strObjekt hat kein __iter__Attribut

>>> hasattr('', '__iter__')
False 

So können Sie eine Überprüfung durchführen

assert hasattr(x, '__iter__')

und dies wird auch AssertionErrorfür jedes andere nicht iterierbare Objekt ein Nettes auslösen.

Bearbeiten: Wie Tim in den Kommentaren erwähnt, funktioniert dies nur in Python 2.x, nicht in 3.x.

Moe
quelle
8
Achtung: In Python 3 wird hasattr('','__iter__')zurückgegeben True. Und das ist natürlich sinnvoll, da Sie über eine Zeichenfolge iterieren können.
Tim Pietzcker
1
"Ja wirklich?" Das wusste ich nicht. Ich dachte immer, dies sei eine elegante Lösung für das Problem, na ja.
Moe
1
Dieser Test hat auf pyodbc.Row nicht funktioniert. Es hat keinen iter __ (), aber es verhält sich mehr oder weniger wie eine Liste (es definiert sogar "__setitem "). Sie können seine Elemente problemlos wiederholen. Die Funktion len () funktioniert und Sie können ihre Elemente indizieren. Ich habe Probleme, die richtige Kombination zu finden, die alle Listentypen abfängt, aber Zeichenfolgen ausschließt. Ich denke, ich werde mich mit einer Überprüfung von " getitem " und " len " zufrieden geben, während ich basestring ausdrücklich ausschließe.
Haridsv
5

Dies ist nicht dazu gedacht, das OP direkt zu beantworten, aber ich wollte einige verwandte Ideen teilen.

Ich war sehr interessiert an der obigen Antwort von @steveha, die ein Beispiel zu geben schien, bei dem das Tippen von Enten zu brechen scheint. Beim zweiten Gedanken deutet sein Beispiel jedoch darauf hin, dass es schwierig ist, sich an die Ententypisierung zu halten, aber es deutet nicht darauf hin, dass dies streine besondere Behandlung verdient.

Schließlich kann ein Nicht- strTyp (z. B. ein benutzerdefinierter Typ, der einige komplizierte rekursive Strukturen beibehält) dazu führen, dass die @ steveha- sreprFunktion eine unendliche Rekursion verursacht. Dies ist zwar zugegebenermaßen eher unwahrscheinlich, wir können diese Möglichkeit jedoch nicht ignorieren. Daher eher als Sonder-Gehäuse strin srepr, sollten wir klären , was wir wollen , sreprwenn ein unendliches Rekursion Ergebnisse tun.

Es scheint, dass ein vernünftiger Ansatz darin besteht, die Rekursion im sreprMoment einfach zu brechen list(arg) == [arg]. Dies würde in der Tat vollständig löst das Problem mit str, ohne isinstance.

Eine wirklich komplizierte rekursive Struktur kann jedoch eine Endlosschleife verursachen, in der dies list(arg) == [arg]niemals geschieht. Daher ist die obige Prüfung zwar nützlich, aber nicht ausreichend. Wir brauchen so etwas wie eine harte Grenze für die Rekursionstiefe.

Mein Punkt ist, dass, wenn Sie vorhaben, mit beliebigen Argumenttypen umzugehen, die Handhabung strüber die Ententypisierung weitaus einfacher ist als die Behandlung der allgemeineren Typen, denen Sie (theoretisch) begegnen können. Wenn Sie also das Bedürfnis haben, strInstanzen auszuschließen , sollten Sie stattdessen verlangen, dass das Argument eine Instanz eines der wenigen Typen ist, die Sie explizit angeben.

max
quelle
1
Hmm, ich mag deine Denkweise. Ich denke, Sie können nicht behaupten, dass mein Code praktisch ist: Es gibt genau einen häufigen Fall, strden der Sonderfallcode behandelt. Aber vielleicht sollte es eine neue Standardeigenschaft geben, die der Code beispielsweise untersuchen kann .__atomic__und die signalisiert, dass etwas nicht weiter aufgeschlüsselt werden kann. Es ist wahrscheinlich zu spät, um atomic()Python eine weitere integrierte Funktion hinzuzufügen , aber vielleicht können wir from collections import atomicetwas hinzufügen oder so.
Steveha
5

Ich finde eine solche Funktion namens is_sequence im Tensorflow .

def is_sequence(seq):
  """Returns a true if its input is a collections.Sequence (except strings).
  Args:
    seq: an input sequence.
  Returns:
    True if the sequence is a not a string and is a collections.Sequence.
  """
  return (isinstance(seq, collections.Sequence)
and not isinstance(seq, six.string_types))

Und ich habe überprüft, ob es Ihren Anforderungen entspricht.

Lerner Zhang
quelle
2

Ich mache das in meinen Testfällen.

def assertIsIterable(self, item):
    #add types here you don't want to mistake as iterables
    if isinstance(item, basestring): 
        raise AssertionError("type %s is not iterable" % type(item))

    #Fake an iteration.
    try:
        for x in item:
            break;
    except TypeError:
        raise AssertionError("type %s is not iterable" % type(item))

Ungetestet an Generatoren, denke ich, bleiben Sie bei der nächsten "Ausbeute", wenn Sie in einen Generator geleitet werden, was die Dinge stromabwärts vermasseln kann. Aber andererseits ist dies ein "unittest"

FlipMcF
quelle
2

Wie wäre es mit "Ententyping"?

try:
    lst = lst + []
except TypeError:
    #it's not a list

oder

try:
    lst = lst + ()
except TypeError:
    #it's not a tuple

beziehungsweise. Dies vermeidet das isinstance/hasattr Introspection-Zeug.

Sie können auch umgekehrt überprüfen:

try:
    lst = lst + ''
except TypeError:
    #it's not (base)string

Alle Varianten ändern den Inhalt der Variablen nicht, sondern implizieren eine Neuzuweisung. Ich bin mir nicht sicher, ob dies unter bestimmten Umständen unerwünscht sein könnte.

Interessanterweise mit der „in place“ Zuordnung +=nicht TypeErrorwürde auf jedem Fall erhöht werden , wenn lsta Liste (kein Tupel ). Deshalb erfolgt die Zuordnung auf diese Weise. Vielleicht kann jemand Licht ins Dunkel bringen, warum das so ist.

utobi
quelle
1

einfachster Weg ... mit anyundisinstance

>>> console_routers = 'x'
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
False
>>>
>>> console_routers = ('x',)
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
True
>>> console_routers = list('x',)
>>> any([isinstance(console_routers, list), isinstance(console_routers, tuple)])
True
abarik
quelle
1

Eine andere Version der Ententypisierung, um stringähnliche Objekte von anderen sequenzähnlichen Objekten zu unterscheiden.

Die Zeichenfolgendarstellung von Zeichenfolgen-ähnlichen Objekten ist die Zeichenfolge selbst. Sie können also überprüfen, ob Sie vom strKonstruktor ein gleiches Objekt zurückerhalten :

# If a string was passed, convert it to a single-element sequence
if var == str(var):
    my_list = [var]

# All other iterables
else: 
    my_list = list(var)

Dies sollte für alle Objekte funktionieren, die mit strund für alle Arten von iterierbaren Objekten kompatibel sind.

Stevepastelan
quelle
0

Python 3 hat Folgendes:

from typing import List

def isit(value):
    return isinstance(value, List)

isit([1, 2, 3])  # True
isit("test")  # False
isit({"Hello": "Mars"})  # False
isit((1, 2))  # False

Um nach Listen und Tupeln zu suchen, wäre es:

from typing import List, Tuple

def isit(value):
    return isinstance(value, List) or isinstance(value, Tuple)
Juha Untinen
quelle
0
assert (type(lst) == list) | (type(lst) == tuple), "Not a valid lst type, cannot be string"
ersh
quelle
2
Ist das ein guter Weg, dies zu tun?
Ersh
1
Willkommen bei SO. Eine Erklärung, warum dieser Code die Frage beantwortet, wäre hilfreich.
Nick
Ja, natürlich verwende ich ähnliche Methoden, da die Pipe als oder so behandelt wird. Sie behaupten, dass der Typ eine Liste oder ein Typ-Tupel sein muss, das einen benutzerdefinierten Nachrichtenfehler für die Fehlerbehandlung ausgibt. Ich glaube, es beantwortet die Frage, aber ich war neugierig, als ob es ein effektiver Weg wäre, dies zu tun, da ich immer noch versuche, den Dreh raus zu bekommen, um den optimiertesten Code zu schreiben. Ich bin mir jedoch nicht sicher, ob in diesem Code Dinge fehlen, die sich wie Listen / Tupel verhalten, aber keine Unterklassen von beiden sind, da die akzeptierte Antwort diese Möglichkeit anspricht. Vielen Dank!
Ersh
-1

Mach das einfach

if type(lst) in (list, tuple):
    # Do stuff
ATOzTOA
quelle
5
isinstance (lst, (Liste, Tupel))
Davi Lima
@DaviLima OK, das ist ein anderer Weg. Type () wird jedoch für eingebaute Typen und isinstance für Klassen empfohlen.
ATOzTOA
-1

in Python> 3.6

import collections
isinstance(set(),collections.abc.Container)
True
isinstance([],collections.abc.Container)
True
isinstance({},collections.abc.Container)
True
isinstance((),collections.abc.Container)
True
isinstance(str,collections.abc.Container)
False
Jean Doux
quelle
2
Bei der letzten Prüfung verwenden Sie einen Typ str, keine Zeichenfolge. Versuchen isinstance('my_string', collections.abc.Container)Sie es und Sie werden sehen, dass es zurückkehren wird True. Dies liegt daran abc.Container, dass die __contains__Methode bereitgestellt wird und die Zeichenfolgen sie natürlich haben.
Georgy
-6

Ich neige dazu (wenn ich wirklich, wirklich musste):

for i in some_var:
   if type(i) == type(list()):
       #do something with a list
   elif type(i) == type(tuple()):
       #do something with a tuple
   elif type(i) == type(str()):
       #here's your string
DrBloodmoney
quelle
5
Sie sollten dies fast nie tun. Was passiert, wenn ich some_vareine Instanz einer Klasse bin , zu der eine Unterklasse gehört list()? Ihr Code hat keine Ahnung, was er damit machen soll, obwohl er unter dem Code "Mach etwas mit einer Liste" perfekt funktioniert. Und Sie müssen sich selten um den Unterschied zwischen einer Liste und einem Tupel kümmern. Entschuldigung, -1.
Steveha
1
Keine Notwendigkeit zu schreiben type(tuple())- reicht aus tuple. Gleiches gilt für die Liste. Außerdem beides strund unicodeverlängern basestring, was der eigentliche Zeichenfolgentyp ist, also möchten Sie stattdessen danach suchen.
Behandle deine Mods gut am
@ DrBloodmoney: Versehentliche Ablehnung. Bitte bearbeiten Sie Ihre Antwort (trivial), damit ich die Ablehnung entfernen kann.
SabreWolfy
Gleichheit scheint mir kein aussagekräftiger Vergleich für Typen zu sein. Ich würde stattdessen auf Identität testen : type(i) is list. Auch type(list())ist nur sich listselbst ... Schließlich funktioniert dies nicht ordnungsgemäß mit Unterklassen. Wenn ies sich tatsächlich um OrderedDict oder eine Art NamedTuple handelt, wird dieser Code als Zeichenfolge behandelt.
Bukzor