यदि कोई वस्तु सूची या टपल (लेकिन स्ट्रिंग नहीं) है तो कैसे जांचें?


444

यह वह है जो मैं सामान्य रूप से यह पता लगाने के लिए करता हूं कि इनपुट ए list/ tuple- है, लेकिन ए नहीं str। क्योंकि कई बार मैं बगों पर ठोकर खा गया जहाँ कोई फ़ंक्शन strगलती से किसी ऑब्जेक्ट को पास करता है , और लक्ष्य फ़ंक्शन यह for x in lstमानकर चलता lstहै कि वास्तव में एक है listया tuple

assert isinstance(lst, (list, tuple))

मेरा प्रश्न है: क्या इसे प्राप्त करने का एक बेहतर तरीका है?


9
प्रकार (lst) सूची है?
जैकलोप

1
नहीं है (कुंजी, six.string_types)
wyx

जवाबों:


332

अजगर 2 में केवल (अजगर 3 नहीं):

assert not isinstance(lst, basestring)

क्या वास्तव में आप चाहते हैं, अन्यथा आप बहुत सी चीजों को याद करेंगे जो सूचियों की तरह काम करती हैं, लेकिन उपवर्ग listया नहीं हैं tuple


91
हां, यह सही उत्तर है। पायथन 3 में, basestringचला गया है, और आप बस के लिए जाँच करते हैं isinstance(lst, str)
चरणवेद

5
बहुत सी चीजें हैं जो आप सूची, उदाहरण के लिए set, जनरेटर अभिव्यक्ति, पुनरावृत्तियों की तरह पुनरावृत्त कर सकते हैं । वहाँ विदेशी चीजें हैं mmap, जैसे कम विदेशी चीजें arrayजो सूचियों की तरह बहुत अधिक कार्य करती हैं, और शायद बहुत अधिक मैं भूल गया हूं।
निक क्रेग-वुड

50
यह ध्यान देने योग्य है कि यह गारंटी नहीं देता है कि lstयह चलने योग्य है, जबकि मूल ने किया था (जैसे एक इंट इस चेक को पास करेगा)
पीटर गिब्सन

11
@PeterGibson - दो का एक संयोजन एक वैध, अधिक प्रतिबंधात्मक जाँच प्रदान करेगा और यह सुनिश्चित करेगा कि 1) लेस्ट चलने योग्य है, 2) लेस्ट एक स्ट्रिंग नहीं है। assert isinstance(lst, (list, tuple)) and assert not isinstance(lst, basestring)
strongMA

4
खैर, यह समाधान केवल स्ट्रिंग व्युत्पन्न प्रकारों के लिए जांचता है, लेकिन पूर्णांक, युगल या किसी अन्य गैर-चलने योग्य प्रकार के बारे में क्या?
एनेको अलोंसो

171

याद रखें कि पायथन में हम "डक टाइपिंग" का उपयोग करना चाहते हैं। तो, कुछ भी जो सूची की तरह काम करता है, उसे सूची के रूप में माना जा सकता है। इसलिए, सूची के प्रकार की जांच न करें, बस यह देखें कि क्या यह सूची की तरह काम करता है।

लेकिन तार एक सूची की तरह भी काम करते हैं, और अक्सर वह नहीं है जो हम चाहते हैं। ऐसे समय होते हैं जब यह एक समस्या है! तो, एक स्ट्रिंग के लिए स्पष्ट रूप से जांचें, लेकिन फिर बतख टाइपिंग का उपयोग करें।

यहाँ एक समारोह है जो मैंने मनोरंजन के लिए लिखा है। यह repr()उस कोण का एक विशेष संस्करण है जो कोण कोष्ठक ('<', '>') में किसी भी अनुक्रम को प्रिंट करता है।

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

यह साफ और सुरुचिपूर्ण है, कुल मिलाकर। लेकिन वह isinstance()चेक वहां क्या कर रहा है? यह एक हैक की तरह है। लेकिन यह जरूरी है।

यह फ़ंक्शन किसी सूची की तरह काम करने वाली चीज़ों पर खुद को पुनरावर्ती कहता है। यदि हम स्ट्रिंग को विशेष रूप से नहीं संभालते हैं, तो यह एक सूची की तरह माना जाएगा, और एक समय में एक वर्ण को विभाजित करेगा। लेकिन फिर पुनरावर्ती कॉल प्रत्येक चरित्र को एक सूची के रूप में मानने की कोशिश करेगा - और यह काम करेगा! यहां तक ​​कि एक-चरित्र स्ट्रिंग सूची के रूप में काम करता है! जब तक स्टैक ओवरफ्लो नहीं हो जाता तब तक फ़ंक्शन स्वयं को पुनरावर्ती रूप से कॉल करता रहेगा।

इस तरह के कार्य, जो कि किए जाने वाले कार्य को तोड़ने वाले प्रत्येक पुनरावर्ती कॉल पर निर्भर करते हैं, को विशेष-केस स्ट्रिंग्स को करना पड़ता है - क्योंकि आप एक-वर्ण स्ट्रिंग के स्तर से नीचे एक स्ट्रिंग को नहीं तोड़ सकते हैं, और यहां तक ​​कि एक भी -च्रेकर स्ट्रिंग एक सूची की तरह काम करता है।

नोट: try/ exceptहमारे इरादों को व्यक्त करने का सबसे साफ तरीका है। लेकिन अगर यह कोड किसी तरह से समय के लिए महत्वपूर्ण था, तो हम यह देखना चाहेंगे कि क्या argयह अनुक्रम है या नहीं। प्रकार का परीक्षण करने के बजाय, हमें शायद व्यवहार का परीक्षण करना चाहिए। यदि यह एक .strip()विधि है, तो यह एक स्ट्रिंग है, इसलिए इसे एक अनुक्रम न मानें; अन्यथा, यदि यह अनुक्रमणीय या पुन: प्रयोज्य है, तो यह एक अनुक्रम है:

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)

संपादित करें: मैंने मूल रूप से एक चेक के साथ ऊपर लिखा था, __getslice__()लेकिन मैंने देखा कि collectionsमॉड्यूल प्रलेखन में, दिलचस्प विधि है __getitem__(); इससे समझ में आता है, कि आप किसी वस्तु को कैसे अनुक्रमित करते हैं। यह अधिक मौलिक लगता है __getslice__()इसलिए मैंने उपरोक्त परिवर्तन किया।


2
@stantonk, ऐसा कहने के लिए धन्यवाद, लेकिन मुझे लगता है कि जब मैंने यह लिखा था तो पहले से ही एक स्वीकृत जवाब था और मैं वास्तव में स्वीकार किए गए उत्तर को बदलने की उम्मीद नहीं करता।
स्टीवेहा

@ ऑस्टेवहा: sreprएक बहुत ही दिलचस्प विचार है। लेकिन मैं इस पर आपसे अलग राय रखता हूं कि क्या इसे विशेष मामले की जरूरत है str। हां, strअब तक का सबसे स्पष्ट और आम पुनरावृत्ति है जो एक अनंत पुनरावृत्ति का कारण होगा srepr। लेकिन मैं आसानी से उपयोगकर्ता-परिभाषित पुनरावृत्तियों की कल्पना कर सकता हूं जो उसी तरह से व्यवहार करते हैं (अच्छे कारण के साथ या बिना)। विशेष-मामले के बजाय str, हमें यह स्वीकार करना चाहिए कि यह दृष्टिकोण एक अनंत पुनरावृत्ति में चल सकता है, और इससे निपटने के लिए किसी तरह से सहमत हो सकता है। मैं एक उत्तर में अपना सुझाव पोस्ट करूंगा।
अधिकतम

1
मुझे लगता है कि यह निश्चित रूप से सही रास्ता है। हालांकि, विशेष मामले (इस परिदृश्य में स्ट्रिंग के) को संभालने के लिए, मुझे लगता है कि हम सवाल पूछने से बेहतर हैं "मानव अंतर कैसे बताएगा?" उदाहरण के लिए, एक फ़ंक्शन तर्क पर विचार करें जो ईमेल पते या एकल ईमेल पते की एक सूची हो सकती है (ध्यान में रखते हुए कि एक स्ट्रिंग केवल पात्रों की एक सूची है)। इस चर को मानव को दे दो। जो यह है वह कैसे बता सकता है? सबसे आसान तरीका मैं सोच सकता हूं कि सूची के प्रत्येक आइटम में कितने वर्ण हैं। यदि यह 1 से अधिक है, तो तर्क निश्चित रूप से वर्णों की सूची नहीं हो सकता है।
जोश

1
मैंने इसके बारे में थोड़ा सोचा है, और कुछ अन्य लोगों के साथ इस पर चर्चा की है, और मुझे लगता srepr()है कि जैसा है ठीक है। हमें एक सूची की तरह चीजों को संभालने के लिए एक पुनरावर्ती फ़ंक्शन की आवश्यकता है जो किसी अन्य सूची के अंदर नेस्टेड है; लेकिन स्ट्रिंग्स के लिए हम नहीं बल्कि उन्हें प्रिंट किया "foo"होगा <'f', 'o', 'o'>। तो एक स्ट्रिंग के लिए एक स्पष्ट जाँच यहाँ अच्छी समझ में आता है। इसके अलावा, वास्तव में डेटा प्रकारों का कोई अन्य उदाहरण नहीं है जहां पुनरावृत्ति हमेशा एक पुनरावृत्ति देता है और पुनरावृत्ति हमेशा स्टैक अतिप्रवाह का कारण बनेगी, इसलिए हमें इसके लिए परीक्षण करने के लिए एक विशेष संपत्ति की आवश्यकता नहीं है ("व्यावहारिकता शुद्धता को हराती है")।
स्टीवेहा

1
यह पायथन 3 में काम नहीं करता है, क्योंकि स्ट्रिंग के पास __iter__()पायथन 3 में एक विधि है, लेकिन पायथन 2 में नहीं। आप में कोष्ठक याद कर रहे हैं is_sequence(), इसे पढ़ना चाहिए: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.

11
सिवाय इसके कि डक टाइपिंग के पायथन मुहावरे का उपयोग नहीं किया जाता है क्योंकि अन्य टिप्पणीकारों ने बताया है (हालांकि यह सीधे और सफाई से प्रश्न का उत्तर देता है)।
सोरेन ब्योर्नस्टैड

7
यह उत्तर दूसरों की तुलना में कम स्वीकार्य है क्योंकि यह बतख टाइपिंग की अनुमति नहीं देता है और यह सबक्लासिंग के साधारण मामले में भी विफल रहता है (एक विशिष्ट उदाहरण नेमटूपल क्लास है)।
फिलिप गॉथिएर

11
"डक टाइपिंग की अनुमति नहीं देना" उत्तर को कोई कम स्वीकार्य नहीं बनाता है, विशेष रूप से यह देखते हुए कि यह उत्तर वास्तव में प्रश्न का उत्तर देता है।
पेट्री

4
मैंने इस उत्तर को बदल दिया है, लेकिन if isinstance( H, (list, tuple) ): ...यह छोटा और स्पष्ट है।
shahar_m

2
वैकल्पिक वाक्यविन्यास:if type(H) in [list, tuple]:
ftefan Schindler

77

पायथन 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")

संस्करण 3.3 में परिवर्तित: संग्रह के लिए मॉड्यूल बेस क्लास को ले जाया गया। पश्चगामी संगतता के लिए, वे इस मॉड्यूल के साथ-साथ संस्करण 3.8 तक दिखाई देते रहेंगे जहां यह काम करना बंद कर देगा।

पायथन 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"

5
वाह! यह वास्तव में अच्छी तरह से काम करता है, और किसी भी अन्य सही उत्तरों की तुलना में बहुत अधिक रसीला है। मुझे नहीं पता था कि अंतर्निहित प्रकार से विरासत में मिला था, collections.Sequenceलेकिन मैंने इसका परीक्षण किया और मैंने देखा कि वे करते हैं। तो करता है xrange। इससे भी बेहतर, यह परीक्षण शामिल नहीं है dict, जिसमें दोनों हैं __getitem__और __iter__
नील मेव्यू

किसी भी विचार का परिणाम क्यों inspect.getmro(list)शामिल नहीं है Sequence? isinstanceजब हम getmroसब कुछ नहीं दिखाते हैं तो हम कैसे समझ सकते हैं कि हम क्या कर सकते हैं ?
स्टीव जोर्गेनसन

@SteveJorgensen विधि संकल्प आदेश कक्षाओं में उपयोग करने के लिए सही विधि की खोज करने के लिए पायथन द्वारा उपयोग किए जाने वाले वर्ग खोज पथ को परिभाषित करता है। Sequenceएक अमूर्त वर्ग है।
सुजानशाक्य

3
Python3 में, आप isinstance (obj, basestring) को isinstance (obj, str) से बदल सकते हैं, और यह काम करना चाहिए।
एड्रियन कीस्टर

2
पायथन 3 में आपको आवश्यकता है और आइंस्टीन (obj, बाइट्स) की नहीं ... यदि आप चीजों की एक सूची चाहते हैं, और न केवल बाइट्स की गणना करने के लिए ...
Erik Aronesty

35

PHP स्वाद के साथ पायथन:

def is_array(var):
    return isinstance(var, (list, tuple))

6
पायथन एक डक-टंकित भाषा है, इसलिए आपको वास्तव में जांचना चाहिए कि क्या var में विशेषता है __getitem__। इसके अलावा नाम भ्रामक है, क्योंकि सरणी मॉड्यूल भी है। और var एक numpy.ndarray या किसी अन्य प्रकार का भी हो सकता है, जिसमें है __getitem__। सही उत्तर के लिए stackoverflow.com/a/1835259/470560 देखें ।
पीरहिल 12

9
@peterhil strभी __getitem__इसलिए आपका चेक बाहर नहीं हैstr
erikbwork

9
तो एक तानाशाही करता है। के लिए जाँच __getitem__यहाँ बुरी सलाह है।
पेट्री

10

सामान्यतया, यह तथ्य कि एक फ़ंक्शन जो किसी ऑब्जेक्ट पर पुनरावृत्ति करता है, तार के साथ-साथ ट्यूपल्स और सूचियों पर काम करता है, बग की तुलना में अधिक विशेषता है। आप निश्चित रूप से कर सकते हैंisinstance से किसी तर्क को जांचने के लिए टाइपिंग या डक का उपयोग हैं , लेकिन आपको क्यों करना चाहिए?

यह एक आलंकारिक प्रश्न की तरह लगता है, लेकिन यह नहीं है। "मुझे तर्क के प्रकार की जांच क्यों करनी चाहिए?" शायद वास्तविक समस्या के समाधान का सुझाव देने वाला है, न कि कथित समस्या का। जब कोई स्ट्रिंग फ़ंक्शन में जाती है तो यह बग क्यों होता है? इसके अलावा: अगर यह एक बग है जब एक स्ट्रिंग इस फ़ंक्शन को पास किया जाता है, तो क्या यह बग भी है अगर कुछ अन्य गैर-सूची / टपल से चलने योग्य इसे पारित किया जाता है? क्यों या क्यों नहीं?

मुझे लगता है कि सवाल का सबसे आम उत्तर यह होने की संभावना है कि जो डेवलपर्स लिखते f("abc")हैं वे फ़ंक्शन से अपेक्षा कर रहे हैं कि वे व्यवहार करेंगे, जैसा कि उन्होंने लिखा है f(["abc"])। शायद ऐसी परिस्थितियां हैं जहां यह डेवलपर्स को खुद से बचाने के लिए अधिक समझ में आता है, क्योंकि यह एक स्ट्रिंग में वर्णों के पुनरावृत्ति के उपयोग के मामले का समर्थन करता है। लेकिन मैं पहले इसके बारे में लंबा और कठिन सोचूंगा।


16
"लेकिन मैं पहले इसके बारे में लंबा और कठिन सोचूंगा।" मैं नहीं होगा यदि फ़ंक्शन को लिस्ट-वाई फ़ंक्शन माना जाता है , तो हाँ, यह उन्हें एक ही व्यवहार करना चाहिए (यानी, एक सूची दी गई, इसे पीछे की ओर थूक दें, जैसी चीजें)। हालाँकि, यदि यह एक ऐसा कार्य है जहाँ किसी एक तर्क या तो एक तार या तार की एक सूची हो सकती है (जो एक बहुत ही सामान्य आवश्यकता है) तो उस फ़ंक्शन का उपयोग करने वाले डेवलपर को मजबूर करना एक सरणी के अंदर हमेशा अपने पैरामीटर में प्रवेश करने के लिए थोड़ा बहुत लगता है। । इसके अलावा, JSON इनपुट के बारे में सोचें कि आप कैसे संभालेंगे। आप निश्चित रूप से एक स्ट्रिंग से अलग वस्तुओं की एक सूची का इलाज करना चाहते हैं।
जॉर्डन रीटर

8

पठनीयता और सर्वोत्तम प्रथाओं के लिए इसे आज़माएँ:

को 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

आशा है ये मदद करेगा।


पायथन 3.6.5:AttributeError: module 'types' has no attribute 'ListType'
जुहा अनटाइनन

1
पायथन 3 में, यह है: from typing import List-> isinstance([1, 2, 3], List= True, और isinstance("asd", List)= False
जूहा अनटाइनन

5

strवस्तु एक नहीं है __iter__विशेषता

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

तो आप एक चेक कर सकते हैं

assert hasattr(x, '__iter__')

और यह AssertionErrorकिसी भी अन्य गैर-चलने योग्य वस्तु के लिए भी एक अच्छा उठाएगा ।

संपादित करें: जैसा कि टिम ने टिप्पणी में उल्लेख किया है, यह केवल अजगर 2.x में काम करेगा, 3.x पर नहीं


8
सावधान: पायथन 3 hasattr('','__iter__')रिटर्न में True। और निश्चित रूप से यह समझ में आता है कि जब से आप एक स्ट्रिंग पर पुनरावृति कर सकते हैं।
तैमू पिएट्ज़कर

1
वास्तव में? मुझे नहीं पता था। मैंने हमेशा सोचा कि यह समस्या का एक सुरुचिपूर्ण समाधान था, ओह अच्छी तरह से।
मो

1
यह परीक्षण pyodbc.Row पर काम नहीं किया। इसका कोई पुनरावृत्ति नहीं है __ () लेकिन यह कमोबेश एक सूची की तरह व्यवहार करता है (यह "__setitem " को भी परिभाषित करता है )। आप इसके तत्वों को ठीक कर सकते हैं। लेन () फ़ंक्शन काम करता है और आप इसके तत्वों को अनुक्रमित कर सकते हैं। मैं सही संयोजन खोजने के लिए संघर्ष कर रहा हूं जो सभी प्रकार की सूची को पकड़ता है, लेकिन तार को बाहर करता है। मुझे लगता है कि मैं बेसिस्ट्रिंग को छोड़कर स्पष्ट रूप से " गेटिटेम " और " लेन " पर एक जांच के लिए समझौता करूंगा।
हरदिवस

5

यह ओपी को सीधे जवाब देने का इरादा नहीं है, लेकिन मैं कुछ संबंधित विचारों को साझा करना चाहता था।

मुझे ऊपर दिए गए @steveha उत्तर में बहुत दिलचस्पी थी, जो एक उदाहरण देता था जहाँ बतख टाइपिंग टूटने लगती है। हालांकि, दूसरे विचार पर, उनका उदाहरण बताता है कि बतख टाइपिंग के अनुरूप करना कठिन है, लेकिन यह सुझाव नहीं देता हैstr किसी भी विशेष हैंडलिंग के योग्य है।

सब के बाद, एक गैर- strप्रकार (जैसे, एक उपयोगकर्ता-परिभाषित प्रकार जो कुछ जटिल पुनरावर्ती संरचनाओं को बनाए रखता है) के कारण @steveha sreprफ़ंक्शन अनंत पुनरावृत्ति का कारण बन सकता है। हालांकि यह स्वाभाविक रूप से असंभव है, हम इस संभावना को नजरअंदाज नहीं कर सकते। इसलिए, बल्कि विशेष आवरण से strमें srepr, हम स्पष्ट करना चाहिए कि हम क्या चाहते हैंsrepr जब एक अनंत प्रत्यावर्तन परिणाम क्या करना है।

ऐसा लग सकता है कि एक उचित दृष्टिकोण sreprपल में पुनरावृत्ति को तोड़ना है list(arg) == [arg]। यह, वास्तव में str, बिना किसी समस्या के पूरी तरह से समस्या को हल करेगा isinstance

हालांकि, वास्तव में जटिल पुनरावर्ती संरचना एक अनंत लूप का कारण बन सकती है जहां list(arg) == [arg]कभी नहीं होता है। इसलिए, जबकि उपरोक्त जाँच उपयोगी है, यह पर्याप्त नहीं है। हमें पुनरावृत्ति की गहराई पर एक कठिन सीमा की तरह कुछ चाहिए।

मेरा कहना है कि यदि आप मनमानी तर्क प्रकारों को संभालने की योजना बनाते हैं, strतो बतख टाइपिंग के माध्यम से संभालना कहीं अधिक सामान्य प्रकारों से निपटने की तुलना में कहीं अधिक आसान है, जो कि (सैद्धांतिक रूप से) मुठभेड़ हो सकती है। इसलिए यदि आपको strउदाहरणों को बाहर करने की आवश्यकता महसूस होती है , तो आपको इसके बजाय मांग करनी चाहिए कि तर्क उन कुछ प्रकारों में से एक है जो आप स्पष्ट रूप से निर्दिष्ट करते हैं।


1
हम्म, मैं आपके सोचने के तरीके को पसंद करता हूं। मुझे लगता है कि आप यह तर्क नहीं दे सकते कि मेरा कोड व्यावहारिक है: बिल्कुल एक सामान्य मामला है, strजो विशेष-केस कोड संभालता है। लेकिन हो सकता है कि एक नई मानक संपत्ति होनी चाहिए जो कोड का निरीक्षण कर सकती है, .__atomic__आइए बताते हैं कि संकेत हैं कि किसी भी चीज को आगे नहीं तोड़ा जा सकता है। शायद atomic()पायथन में एक और बिल्टइन फ़ंक्शन को जोड़ने के लिए बहुत देर हो चुकी है , लेकिन शायद हम जोड़ सकते हैं from collections import atomicया कुछ और कर सकते हैं ।
स्टीवेहा

5

मुझे इस तरह के एक फ़ंक्शन का नाम मिला है जिसका नाम टेंसोफ़्लो है

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))

और मैंने सत्यापित किया है कि यह आपकी आवश्यकताओं को पूरा करता है।


2

मैं अपने वृषण में ऐसा करता हूं।

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))

जनरेटर पर असंतुष्ट, मुझे लगता है कि आप जनरेटर में पारित होने पर अगली 'उपज' पर छोड़ दिए जाते हैं, जो नीचे की ओर चीजों को पेंच कर सकता है। लेकिन फिर, यह एक 'अनटाइस्ट' है


2

"बतख टाइपिंग" तरीके से, कैसे के बारे में

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

या

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

क्रमशः। यह isinstance/ hasattrआत्मनिरीक्षण सामग्री से बचा जाता है ।

आप इसके विपरीत की जाँच भी कर सकते हैं:

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

सभी वेरिएंट वास्तव में वेरिएबल की सामग्री को नहीं बदलते हैं, लेकिन एक पुनर्मूल्यांकन का अर्थ है। मैं अनिश्चित हूं कि क्या यह कुछ परिस्थितियों में अवांछनीय हो सकता है।

दिलचस्प है, "जगह" असाइनमेंट के साथ किसी भी मामले में उठाया +=नहीं TypeErrorजाएगा यदि lstएक सूची है (एक ट्यूपल नहीं )। इसलिए असाइनमेंट इस तरह से किया जाता है। हो सकता है कि कोई इस पर प्रकाश डाल सकता है।


1

सबसे सरल तरीका ... का उपयोग कर anyऔरisinstance

>>> 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

1

अन्य अनुक्रम जैसी वस्तुओं से स्ट्रिंग-जैसी वस्तुओं को अलग करने में मदद करने के लिए डक-टाइपिंग का दूसरा संस्करण।

स्ट्रिंग-जैसे ऑब्जेक्ट्स का स्ट्रिंग प्रतिनिधित्व स्वयं स्ट्रिंग है, इसलिए आप यह जांच सकते हैं कि क्या आपको strकंस्ट्रक्टर से एक समान ऑब्जेक्ट वापस मिलता है :

# 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)

यह सभी वस्तुओं के साथ strऔर सभी प्रकार की चलने वाली वस्तुओं के लिए काम करना चाहिए ।


0

पायथन 3 में यह है:

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

इसलिए दोनों सूचियों और टुपल्स के लिए जाँच करने के लिए, यह होगा:

from typing import List, Tuple

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

0
assert (type(lst) == list) | (type(lst) == tuple), "Not a valid lst type, cannot be string"

2
क्या यह ऐसा करने का एक अच्छा तरीका है?
इर्श १h ’

1
एसओ में आपका स्वागत है। यह कोड इस सवाल का जवाब क्यों देता है, इस बारे में व्याख्या उपयोगी होगी।
निक

हां, मैं इसके समान तरीकों का उपयोग करता हूं क्योंकि पाइप को एक के रूप में माना जाता है या इसलिए आप यह दावा कर रहे हैं कि टाइप एक सूची होनी चाहिए या त्रुटि से निपटने के लिए कस्टम संदेश त्रुटि टाइप करने के लिए टपल का उत्पादन होना चाहिए। मेरा मानना ​​है कि यह प्रश्न का उत्तर देता है, लेकिन मैं उत्सुक था जैसे कि यह ऐसा करने का एक प्रभावी तरीका है क्योंकि मैं अभी भी सबसे अधिक अनुकूलित कोड लिखने की कोशिश कर रहा हूं। मैं अनिश्चित हूँ लेकिन अगर यह कोड उन चीज़ों से छूट जाता है जो सूचियों / ट्यूपल्स की तरह काम कर सकती हैं, लेकिन दोनों में से कोई भी उप-वर्ग नहीं हैं, तो स्वीकार किए जाते हैं कि उत्तर कैसे सम्भव है। धन्यवाद!
इरश

-1

बस यह करो

if type(lst) in (list, tuple):
    # Do stuff

5
isinstance (lst, (list, tuple))
Davi Lima

@DaviLima ठीक है, यह एक और तरीका है। लेकिन इन-बिल्ट प्रकारों के लिए टाइप () की सिफारिश की जाती है और कक्षाओं के लिए आइंस्टीन।
ATOzTOA

-1

अजगर में> 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

2
अंतिम जांच में आप एक प्रकार का उपयोग करते हैं str, न कि एक स्ट्रिंग। कोशिश करो isinstance('my_string', collections.abc.Container)और आप देखेंगे कि यह वापस आ जाएगा True। यह इसलिए है क्योंकि विधि की abc.Containerआपूर्ति __contains__, और तार यह है, निश्चित रूप से।
जॉर्जी

-6

मैं ऐसा करता हूं (यदि मैं वास्तव में, वास्तव में था):

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

5
आपको लगभग ऐसा कभी नहीं करना चाहिए। यदि मैं some_varएक वर्ग का एक उदाहरण है जो उपवर्ग है तो क्या होता है list()? आपके कोड को यह पता नहीं होगा कि इसके साथ क्या करना है, भले ही यह "सूची के साथ कुछ करें" कोड के तहत पूरी तरह से काम करेगा। और आपको शायद ही कभी एक सूची और टुपल के बीच अंतर के बारे में परवाह करने की आवश्यकता होती है। क्षमा करें, -1।
स्टीवेहा

1
लिखने की जरूरत नहीं है type(tuple())- tupleकरेंगे। सूची के लिए भी। इसके अलावा, दोनों strऔर unicodeविस्तारित होते हैं basestring, जो कि वास्तविक स्ट्रिंग प्रकार है, इसलिए आप इसके बजाय जांच करना चाहते हैं।
अपने मॉड का अच्छी तरह से इलाज करें

@DrBloodmoney: आकस्मिक गिरावट। कृपया (तुच्छ रूप से) अपने उत्तर को हटाने के लिए मुझे सक्षम करने के लिए अपना उत्तर संपादित करें।
सब्रेवुल्फी

समानता मेरे लिए, प्रकारों के लिए एक सार्थक तुलना की तरह प्रतीत नहीं होती है। मैं पहचान के लिए के बजाय परीक्षण चाहते हैं: type(i) is list। इसके अलावा, type(list())बस listखुद है ... अंत में, यह उपवर्गों के साथ इनायत से काम नहीं करता है। यदि iवास्तव में है और आर्डर डिडक्टेड है, या किसी प्रकार का नामांकित है, तो यह कोड एक स्ट्रिंग के रूप में व्यवहार करेगा।
bukzor
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.