यदि कोई स्ट्रिंग एक int का प्रतिनिधित्व करता है, तो मैं कोशिश / उपयोग के बिना कैसे देख सकता हूं?


466

क्या यह बताने का कोई तरीका है कि क्या एक स्ट्रिंग एक पूर्णांक (जैसे '3', '-17'लेकिन नहीं '3.14'या नहीं 'asfasfas') का प्रतिनिधित्व करता है बिना किसी कोशिश के / तंत्र को छोड़कर?

is_int('3.14') = False
is_int('-7')   = True

23
दोनों इसे "कठिन रास्ता" करने की कोशिश क्यों कर रहे हैं? प्रयास के सिवाय / क्या गलत है?
S.Lott

5
हाँ, कोशिश करने के सिवाय / क्या गलत है? अनुमति के लिए माफी मांगना बेहतर है।
2:12 बजे mk12

53
मैं पूछूंगा कि इस सरल चीज़ को प्रयास / छोड़कर की आवश्यकता क्यों होनी चाहिए? अपवाद प्रणाली एक जटिल जानवर है, लेकिन यह एक साधारण समस्या है।
ऐवर

13
@ Aivar ने FUD फैलाना बंद किया। एक एकल प्रयास / ब्लॉक को छोड़कर "जटिल" भी नहीं होता है।
२३:२१

47
यह वास्तव में FUD नहीं है, हालांकि। आप प्रभावी ढंग से कोड की 4 पंक्तियाँ लिख रहे होंगे, किसी चीज़ को उड़ाने की अपेक्षा करेंगे, उस अपवाद को पकड़ेंगे और एक लाइनर का उपयोग करने के बजाय अपना डिफ़ॉल्ट करेंगे।
एंडरसनॉम

जवाबों:


398

यदि आप वास्तव में try/exceptसभी जगह उपयोग करने से केवल नाराज हैं , तो कृपया एक सहायक फ़ंक्शन लिखें:

def RepresentsInt(s):
    try: 
        int(s)
        return True
    except ValueError:
        return False

>>> print RepresentsInt("+123")
True
>>> print RepresentsInt("10.0")
False

पायथन को पूर्णांक मानने वाले सभी तारों को कवर करने के लिए यह अधिक कोड होगा। मैं कहता हूं कि इस पर बस पाइथोनिक बनो।


124
तो यह जटिल तंत्र के साथ सरल समस्या को हल करने के लिए पायथोनिक है? फंक्शन के अंदर "int" लिखे जाने का पता लगाने के लिए एक एल्गोरिथ्म है - मैं नहीं देखता कि यह बूलियन फ़ंक्शन के रूप में क्यों उजागर नहीं हुआ है।
आइवर

79
@ ऐवर: यह 5 लाइन फ़ंक्शन एक जटिल तंत्र नहीं है।
त्रिपिटक

34
सिवाय:>>> print RepresentsInt(10.0) True >>> print RepresentsInt(10.06) True
Dannid

5
मुझे लगता है कि यह "पायथोनिक" इस अर्थ में है कि अगर पायथन को लगता है कि स्ट्रिंग एक इंट है, तो आपका प्रोग्राम करता है। यदि पायथन बदलता है, तो आपका प्रोग्राम, और कोड की एक भी लाइन को बदले बिना करता है। उसमें कुछ मूल्य है। यह परिस्थितियों के आधार पर सही काम हो सकता है।
शाविस

57
मुझे नहीं पता कि यह क्यों स्वीकार किया गया उत्तर है या इसमें बहुत सारे उतार-चढ़ाव हैं, क्योंकि यह ओपी के लिए पूछ रहा है के बिल्कुल विपरीत है।
फियरलेस

755

सकारात्मक पूर्णांकों के साथ आप उपयोग कर सकते हैं .isdigit:

>>> '16'.isdigit()
True

हालांकि यह नकारात्मक पूर्णांक के साथ काम नहीं करता है। मान लें कि आप निम्नलिखित प्रयास कर सकते हैं:

>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True

यह '16.0'प्रारूप के साथ काम नहीं करेगा , जो intइस अर्थ में कास्टिंग के समान है।

संपादित करें :

def check_int(s):
    if s[0] in ('-', '+'):
        return s[1:].isdigit()
    return s.isdigit()

6
यह एक अतिरिक्त विशेष मामले के बिना "+17" को संभालता नहीं है।
ब्रायन ओकली

1
आपको बीओटीएच मामलों के लिए परीक्षण करना होगा: लैम्ब्डा एस: एस.डिसिजिट () या (एस.स्टार्टस्विथ ('-') और एस [1:] .digit ())
लूट

4
@ रॉबर्टो: बेशक आपको करना चाहिए! और मुझे यकीन है कि आप ऐसा करने में सक्षम हैं!
साइलेंटगॉस्ट

22
नोट: u'²'.isdigit()सत्य है, लेकिन int(u'²')मान बढ़ाता है। u.isdecimal()इसके बजाय उपयोग करें । str.isdigit()पायथन 2 पर लोकेल-डिपेंडेंट है
6

4
check_int('')लौटने के बजाय एक अपवाद False
जुटाएंगे

96

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

मैं PHP, पर्ल, रूबी, सी, और यहां तक ​​कि पागल शेल को पूर्णांक-हुड के लिए एक स्ट्रिंग का परीक्षण करने के लिए सरल कार्य करने वाला था, लेकिन उन मान्यताओं को सत्यापित करने में परिश्रम ने मुझे उलझा दिया! जाहिर तौर पर यह कमी एक आम बीमारी है।

यहां ब्रूनो के पोस्ट का एक त्वरित और गंदा संपादन है:

import sys, time, re

g_intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$")

testvals = [
    # integers
    0, 1, -1, 1.0, -1.0,
    '0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0', '06',
    # non-integers
    'abc 123',
    1.1, -1.1, '1.1', '-1.1', '+1.1',
    '1.1.1', '1.1.0', '1.0.1', '1.0.0',
    '1.0.', '1..0', '1..',
    '0.0.', '0..0', '0..',
    'one', object(), (1,2,3), [1,2,3], {'one':'two'},
    # with spaces
    ' 0 ', ' 0.', ' .0','.01 '
]

def isInt_try(v):
    try:     i = int(v)
    except:  return False
    return True

def isInt_str(v):
    v = str(v).strip()
    return v=='0' or (v if v.find('..') > -1 else v.lstrip('-+').rstrip('0').rstrip('.')).isdigit()

def isInt_re(v):
    import re
    if not hasattr(isInt_re, 'intRegex'):
        isInt_re.intRegex = re.compile(r"^([+-]?[1-9]\d*|0)$")
    return isInt_re.intRegex.match(str(v).strip()) is not None

def isInt_re2(v):
    return g_intRegex.match(str(v).strip()) is not None

def check_int(s):
    s = str(s)
    if s[0] in ('-', '+'):
        return s[1:].isdigit()
    return s.isdigit()    


def timeFunc(func, times):
    t1 = time.time()
    for n in range(times):
        for v in testvals: 
            r = func(v)
    t2 = time.time()
    return t2 - t1

def testFuncs(funcs):
    for func in funcs:
        sys.stdout.write( "\t%s\t|" % func.__name__)
    print()
    for v in testvals:
        if type(v) == type(''):
            sys.stdout.write("'%s'" % v)
        else:
            sys.stdout.write("%s" % str(v))
        for func in funcs:
            sys.stdout.write( "\t\t%s\t|" % func(v))
        sys.stdout.write("\r\n") 

if __name__ == '__main__':
    print()
    print("tests..")
    testFuncs((isInt_try, isInt_str, isInt_re, isInt_re2, check_int))
    print()

    print("timings..")
    print("isInt_try:   %6.4f" % timeFunc(isInt_try, 10000))
    print("isInt_str:   %6.4f" % timeFunc(isInt_str, 10000)) 
    print("isInt_re:    %6.4f" % timeFunc(isInt_re, 10000))
    print("isInt_re2:   %6.4f" % timeFunc(isInt_re2, 10000))
    print("check_int:   %6.4f" % timeFunc(check_int, 10000))

यहाँ प्रदर्शन तुलना परिणाम हैं:

timings..
isInt_try:   0.6426
isInt_str:   0.7382
isInt_re:    1.1156
isInt_re2:   0.5344
check_int:   0.3452

एसी विधि इसे एक बार स्कैन करके, और किया जा सकता है। एसी विधि जो एक बार स्ट्रिंग को स्कैन करती है वह राइट थिंग होगी, मुझे लगता है।

संपादित करें:

मैंने पायथन 3.5 में काम करने के लिए उपरोक्त कोड को अपडेट किया है, और वर्तमान में सबसे अधिक वोट किए गए उत्तर से check_int फ़ंक्शन को शामिल करने के लिए, और वर्तमान सबसे लोकप्रिय regex का उपयोग करने के लिए जिसे मैं पूर्णांक-हुड के लिए परीक्षण के लिए पा सकता हूं। यह रेगेक्स 'एबीसी 123' जैसे तार को खारिज करता है। मैंने परीक्षण मान के रूप में 'abc 123' जोड़ा है।

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

अंतर्निहित इंट () फ़ंक्शन चुपचाप एक फ्लोटिंग पॉइंट नंबर के आंशिक भाग को काटता है और दशमलव से पहले पूर्णांक भाग को लौटाता है, जब तक कि फ़्लोटिंग पॉइंट नंबर पहली बार स्ट्रिंग में परिवर्तित नहीं हो जाता है।

Check_int () फ़ंक्शन 0.0 और 1.0 जैसे मूल्यों के लिए गलत है (जो तकनीकी रूप से पूर्णांक हैं) और '06' जैसे मूल्यों के लिए सही है।

यहाँ वर्तमान (पायथन 3.5) परीक्षा परिणाम हैं:

                  isInt_try |       isInt_str       |       isInt_re        |       isInt_re2       |   check_int   |
    0               True    |               True    |               True    |               True    |       True    |
    1               True    |               True    |               True    |               True    |       True    |
    -1              True    |               True    |               True    |               True    |       True    |
    1.0             True    |               True    |               False   |               False   |       False   |
    -1.0            True    |               True    |               False   |               False   |       False   |
    '0'             True    |               True    |               True    |               True    |       True    |
    '0.'            False   |               True    |               False   |               False   |       False   |
    '0.0'           False   |               True    |               False   |               False   |       False   |
    '1'             True    |               True    |               True    |               True    |       True    |
    '-1'            True    |               True    |               True    |               True    |       True    |
    '+1'            True    |               True    |               True    |               True    |       True    |
    '1.0'           False   |               True    |               False   |               False   |       False   |
    '-1.0'          False   |               True    |               False   |               False   |       False   |
    '+1.0'          False   |               True    |               False   |               False   |       False   |
    '06'            True    |               True    |               False   |               False   |       True    |
    'abc 123'       False   |               False   |               False   |               False   |       False   |
    1.1             True    |               False   |               False   |               False   |       False   |
    -1.1            True    |               False   |               False   |               False   |       False   |
    '1.1'           False   |               False   |               False   |               False   |       False   |
    '-1.1'          False   |               False   |               False   |               False   |       False   |
    '+1.1'          False   |               False   |               False   |               False   |       False   |
    '1.1.1'         False   |               False   |               False   |               False   |       False   |
    '1.1.0'         False   |               False   |               False   |               False   |       False   |
    '1.0.1'         False   |               False   |               False   |               False   |       False   |
    '1.0.0'         False   |               False   |               False   |               False   |       False   |
    '1.0.'          False   |               False   |               False   |               False   |       False   |
    '1..0'          False   |               False   |               False   |               False   |       False   |
    '1..'           False   |               False   |               False   |               False   |       False   |
    '0.0.'          False   |               False   |               False   |               False   |       False   |
    '0..0'          False   |               False   |               False   |               False   |       False   |
    '0..'           False   |               False   |               False   |               False   |       False   |
    'one'           False   |               False   |               False   |               False   |       False   |
    <obj..>         False   |               False   |               False   |               False   |       False   |
    (1, 2, 3)       False   |               False   |               False   |               False   |       False   |
    [1, 2, 3]       False   |               False   |               False   |               False   |       False   |
    {'one': 'two'}  False   |               False   |               False   |               False   |       False   |
    ' 0 '           True    |               True    |               True    |               True    |       False   |
    ' 0.'           False   |               True    |               False   |               False   |       False   |
    ' .0'           False   |               False   |               False   |               False   |       False   |
    '.01 '          False   |               False   |               False   |               False   |       False   |

अभी-अभी मैंने इस फंक्शन को जोड़ने की कोशिश की:

def isInt_float(s):
    try:
        return float(str(s)).is_integer()
    except:
        return False

यह लगभग और साथ ही check_int (0.3486) करता है और यह 1.0 और 0.0 और +1.0 और 0. और .0 जैसे मूल्यों के लिए सही है। लेकिन यह '06' के लिए भी सही है, इसलिए। जहर उठाओ, मुझे लगता है।


शायद इसका एक हिस्सा इस तथ्य से आता है कि एक पूर्णांक स्वयं एक मनमाना है। एक प्रोग्रामिंग सिस्टम यह मानने की विलासिता नहीं ले सकता है कि यह हमेशा दशमलव प्रतिनिधित्व करने वाला है। 0x4df, कुछ स्थानों पर एक वैध पूर्णांक है, और 0891 अन्य में नहीं है। मुझे लगता है कि इस तरह के चेक में यूनिकोड दिए जाने से क्या हो सकता है।
17

3
समय के लिए +1। मैं मानता हूं कि इस तरह के एक साधारण प्रश्न के लिए यह पूरा अपवाद व्यवसाय वास्तव में सुरुचिपूर्ण नहीं है। आप इस तरह की एक आम समस्या के लिए सहायक विधि में एक निर्माण की उम्मीद करेंगे ...
रिकी सिप

9
मुझे पता है कि यह धागा मूल रूप से निष्क्रिय है, लेकिन रन-टाइम पर विचार करने के लिए +1। लाइन की लंबाई हमेशा अंतर्निहित जटिलता का संकेत नहीं है; और यह सुनिश्चित करें, एक कोशिश / छोड़कर पराक्रम नज़र सरल (और, पढ़ने में आसान है जो बहुत महत्वपूर्ण है), लेकिन यह है एक महंगा आपरेशन। मैं चाहता हूँ कि वरीयता पदानुक्रम हमेशा निम्नलिखित की तरह कुछ दिखना चाहिए: 1. स्पष्ट समाधान (साइलेंटगॉस्ट्स) पढ़ने के लिए एक आसान। 2. अंतर्निहित समाधान (ट्रिप्टिक) पढ़ने के लिए एक आसान। 3. कोई तीन नहीं है।
एरिक हम्फ्री

1
इस तरह के एक उचित लगने वाले विषय के बारे में आपके दौरे की जांच के लिए धन्यवाद। मैं isInt_str (), पायथोनिक या नहीं के साथ जाऊँगा। जो मुझे परेशान कर रहा है वह यह है कि मुझे v.find ('..') के अर्थ के बारे में कुछ भी नहीं मिला है। क्या वह विशेष प्रकार का विशेष-वाक्य-विन्यास या संख्यात्मक-स्ट्रिंग का एक किनारा-मामला है?
जैकलेमरमेर

3
हां, थोड़ा दिनांकित लेकिन फिर भी वास्तव में अच्छा और प्रासंगिक विश्लेषण। पायथन में 3.5 tryअधिक कुशल है: isInt_try: 0.6552 / isInt_str: 0.6396 / isInt_re: 1.0296 / isInt_re2: 0.5168।
डेव

39

str.isdigit() चाल चलनी चाहिए।

उदाहरण:

str.isdigit("23") ## True
str.isdigit("abc") ## False
str.isdigit("23.4") ## False

संपादित करें : जैसा कि @BuzzMoschetti ने बताया है, यह तरीका माइनस नंबर (जैसे, "-23" ) के लिए विफल होगा । मामले में अपने input_num 0 की तुलना में कम हो सकता है, उपयोग re.sub (regex_search, regex_replace, सामग्री) लागू करने से पहले str.isdigit () । उदाहरण के लिए:

import re
input_num = "-23"
input_num = re.sub("^-", "", input_num) ## "^" indicates to remove the first "-" only
str.isdigit(input_num) ## True

1
क्योंकि -23 उपज झूठी होती है।
बज़ मोर्चेटी

1
@BuzzMoschetti आप सही कह रहे हैं। ठीक करने के लिए एक त्वरित तरीका str.isdigit () लागू करने से पहले re.replace (regex_search, regex_replace, सामग्री) द्वारा ऋण चिह्न को हटाने है
Catbuilts

27

एक नियमित अभिव्यक्ति का उपयोग करें:

import re
def RepresentsInt(s):
    return re.match(r"[-+]?\d+$", s) is not None

यदि आपको दशमलव अंश भी स्वीकार करना चाहिए:

def RepresentsInt(s):
    return re.match(r"[-+]?\d+(\.0*)?$", s) is not None

बेहतर प्रदर्शन के लिए यदि आप अक्सर ऐसा कर रहे हैं, तो केवल एक बार उपयोग करके नियमित अभिव्यक्ति संकलित करें re.compile()


19
+1: पता चलता है कि यह भयानक जटिल और महंगा है जब कोशिश / अपवाद के साथ तुलना की जाती है।
एस.लूट

2
मुझे लगता है कि यह मूल रूप से @SilentGhost द्वारा प्रस्तुत 'isnumeric' समाधान का कस्टम संस्करण है।
ग्रेग

@Greg: चूंकि @SilentGhost संकेतों को सही ढंग से कवर नहीं करता है, यह संस्करण वास्तव में काम करता है।
S.Lott

1
@ एस.लॉट: निश्चित रूप से, एसओ पर पोस्ट करने में सक्षम कोई भी, संकेतों को कवर करने के लिए मेरे उदाहरण का विस्तार करने में सक्षम होगा।
साइलेंटगॉस्ट

2
नियमित अभिव्यक्ति अस्तित्व में सबसे जटिल और अस्पष्ट बात के बारे में है, मुझे लगता है कि ऊपर की साधारण जांच काफी अधिक स्पष्ट है, भले ही मुझे लगता है कि यह अभी भी बदसूरत है, यह बदसूरत है।
16

18

RegEx का उचित समाधान ग्रेग हेगिल और नोवेल के विचारों को मिलाएगा, लेकिन वैश्विक चर का उपयोग नहीं करेगा। आप एक विशेषता को विधि में संलग्न करके इसे पूरा कर सकते हैं। इसके अलावा, मुझे पता है कि यह एक विधि में आयात करने के लिए पर आधारित है, लेकिन मैं जो करने जा रहा हूं वह http://peak.telecommunity.com/DevCenter/Importing#lazy-imports जैसे "आलसी मॉड्यूल" प्रभाव है

संपादित करें: मेरी अब तक की पसंदीदा तकनीक स्ट्रिंग ऑब्जेक्ट के विशेष तरीकों का उपयोग करना है।

#!/usr/bin/env python

# Uses exclusively methods of the String object
def isInteger(i):
    i = str(i)
    return i=='0' or (i if i.find('..') > -1 else i.lstrip('-+').rstrip('0').rstrip('.')).isdigit()

# Uses re module for regex
def isIntegre(i):
    import re
    if not hasattr(isIntegre, '_re'):
        print("I compile only once. Remove this line when you are confident in that.")
        isIntegre._re = re.compile(r"[-+]?\d+(\.0*)?$")
    return isIntegre._re.match(str(i)) is not None

# When executed directly run Unit Tests
if __name__ == '__main__':
    for obj in [
                # integers
                0, 1, -1, 1.0, -1.0,
                '0', '0.','0.0', '1', '-1', '+1', '1.0', '-1.0', '+1.0',
                # non-integers
                1.1, -1.1, '1.1', '-1.1', '+1.1',
                '1.1.1', '1.1.0', '1.0.1', '1.0.0',
                '1.0.', '1..0', '1..',
                '0.0.', '0..0', '0..',
                'one', object(), (1,2,3), [1,2,3], {'one':'two'}
            ]:
        # Notice the integre uses 're' (intended to be humorous)
        integer = ('an integer' if isInteger(obj) else 'NOT an integer')
        integre = ('an integre' if isIntegre(obj) else 'NOT an integre')
        # Make strings look like strings in the output
        if isinstance(obj, str):
            obj = ("'%s'" % (obj,))
        print("%30s is %14s is %14s" % (obj, integer, integre))

और कक्षा के कम साहसी सदस्यों के लिए, यहाँ आउटपुट है:

I compile only once. Remove this line when you are confident in that.
                             0 is     an integer is     an integre
                             1 is     an integer is     an integre
                            -1 is     an integer is     an integre
                           1.0 is     an integer is     an integre
                          -1.0 is     an integer is     an integre
                           '0' is     an integer is     an integre
                          '0.' is     an integer is     an integre
                         '0.0' is     an integer is     an integre
                           '1' is     an integer is     an integre
                          '-1' is     an integer is     an integre
                          '+1' is     an integer is     an integre
                         '1.0' is     an integer is     an integre
                        '-1.0' is     an integer is     an integre
                        '+1.0' is     an integer is     an integre
                           1.1 is NOT an integer is NOT an integre
                          -1.1 is NOT an integer is NOT an integre
                         '1.1' is NOT an integer is NOT an integre
                        '-1.1' is NOT an integer is NOT an integre
                        '+1.1' is NOT an integer is NOT an integre
                       '1.1.1' is NOT an integer is NOT an integre
                       '1.1.0' is NOT an integer is NOT an integre
                       '1.0.1' is NOT an integer is NOT an integre
                       '1.0.0' is NOT an integer is NOT an integre
                        '1.0.' is NOT an integer is NOT an integre
                        '1..0' is NOT an integer is NOT an integre
                         '1..' is NOT an integer is NOT an integre
                        '0.0.' is NOT an integer is NOT an integre
                        '0..0' is NOT an integer is NOT an integre
                         '0..' is NOT an integer is NOT an integre
                         'one' is NOT an integer is NOT an integre
<object object at 0x103b7d0a0> is NOT an integer is NOT an integre
                     (1, 2, 3) is NOT an integer is NOT an integre
                     [1, 2, 3] is NOT an integer is NOT an integre
                {'one': 'two'} is NOT an integer is NOT an integre

4
मैं सहमत हूँ कि मेरा टेस्ट सूट ओवरकिल है। मुझे यह साबित करना पसंद है कि जब मैं इसे लिखता हूं तो मेरा कोड काम करता है। लेकिन क्या आपको लगता है कि मेरा आयताकार कार्य ओवरकिल है? पक्का नहीं।
ब्रूनो ब्रोंस्की

1
मुझे बिना किसी टिप्पणी के केवल एक डाउन वोट मिला। लोगों के साथ क्या है? मैं समझता हूं कि सहस्त्राब्दी अब "पसंद" का उपयोग "रीड रिसिप्ट" के रूप में कर रहे हैं। लेकिन क्या वे अब मतों का उपयोग "मार्कर को चुनने की विधि नहीं" के रूप में कर रहे हैं? हो सकता है कि उन्हें एहसास न हो कि यह 2 अंकों को घटाता है आपकी ओट प्रतिष्ठा वोट देने के लिए एक जवाब है। SO / SE ऐसा करता है कि केवल गलत सूचना के कारण मतदान को प्रोत्साहित करने के लिए, जिस स्थिति में मुझे उम्मीद है कि आप एक टिप्पणी छोड़ देंगे
ब्रूनो ब्रोंस्की

5
>>> "+7".lstrip("-+").isdigit()
True
>>> "-7".lstrip("-+").isdigit()
True
>>> "7".lstrip("-+").isdigit()
True
>>> "13.4".lstrip("-+").isdigit()
False

तो आपका कार्य होगा:

def is_int(val):
   return val[1].isdigit() and val.lstrip("-+").isdigit()

1
is_int ("2") IndexError उठाता है।
आट्टिकू

4

ग्रेग हेविगिल का दृष्टिकोण कुछ घटकों को याद कर रहा था: अग्रणी "^" केवल स्ट्रिंग की शुरुआत से मेल खाता है, और पहले से फिर से संकलित कर रहा है। लेकिन यह दृष्टिकोण आपको एक कोशिश से बचने की अनुमति देगा: निर्वासन:

import re
INT_RE = re.compile(r"^[-]?\d+$")
def RepresentsInt(s):
    return INT_RE.match(str(s)) is not None

मुझे दिलचस्पी होगी कि आप कोशिश से बचने की कोशिश क्यों कर रहे हैं: सिवाय?


1
शैली की बात। मुझे लगता है कि "कोशिश / सिवाय" का उपयोग केवल वास्तविक त्रुटियों के साथ किया जाना चाहिए, न कि सामान्य कार्यक्रम प्रवाह के साथ।
एडम मटन

2
@Udi Pasmon: पायथन "सामान्य" प्रोग्राम फ्लो को छोड़कर प्रयास के काफी भारी उपयोग करता है। उदाहरण के लिए, प्रत्येक पुनरावृत्त एक उठाए गए अपवाद के साथ बंद हो जाता है।
एस.लॉट

3
-1: यद्यपि रेगेक्स को संकलित करने में आपका संकेत सही है, फिर भी आप ग्रेग को दूसरे संदर्भ में समझने में गलत हैं: स्ट्रिंग की शुरुआत के मुकाबले मैच करते हैं , इसलिए पैटर्न में ^ वास्तव में बेमानी है। (यह अलग है जब आप re.search का उपयोग करते हैं)।
थॉमस

S.Lott - क्या यह अजगर में उचित प्रवाह माना जाता है? यह अन्य भाषाओं से कैसे भिन्न है? शायद यह एक अलग सवाल के लायक है।
एडम मटन

1
पायथन के भारी प्रयास / उपयोग को छोड़कर यहाँ SO पर कवर किया गया है। '[अजगर] को छोड़कर' के लिए एक खोज का प्रयास करें
S.Lott

4

मुझे यह हर समय करना पड़ता है, और मेरे पास कोशिश को छोड़कर पैटर्न का उपयोग करने के लिए एक हल्के लेकिन संयुक्त रूप से तर्कहीन टकराव है। मैं इसका उपयोग करता हूं:

all([xi in '1234567890' for xi in x])

यह नकारात्मक संख्याओं को समायोजित नहीं करता है, इसलिए आप एक ऋण चिह्न (यदि कोई हो) को निकाल सकते हैं, और फिर जांच सकते हैं कि परिणाम 0-9 तक अंक शामिल हैं:

all([xi in '1234567890' for xi in x.replace('-', '', 1)])

यदि आप सुनिश्चित नहीं हैं कि इनपुट एक स्ट्रिंग है, तो आप x से str () पास कर सकते हैं:

all([xi in '1234567890' for xi in str(x).replace('-', '', 1)])

कम से कम दो (बढ़त) मामले हैं जहां यह अलग हो जाता है:

  1. यह विभिन्न वैज्ञानिक और / या घातीय संकेतन (जैसे 1.2E3, 10 ^ 3, आदि) के लिए काम नहीं करता है - दोनों फाल्स वापस कर देंगे। मुझे नहीं लगता कि अन्य उत्तरों ने इसे समायोजित किया है, और यहां तक ​​कि पायथन 3.8 में भी असंगत राय है, क्योंकि type(1E2)देता है<class 'float'> जबकि type(10^2)देता है<class 'int'>
  2. एक खाली स्ट्रिंग इनपुट ट्रू देता है।

इसलिए यह हर संभव इनपुट के लिए काम नहीं करेगा , लेकिन अगर आप वैज्ञानिक संकेतन, घातीय संकेतन और खाली तार को बाहर कर सकते हैं, तो यह एक ठीक एक लाइन की जांच है जो रिटर्नFalse अगर x एक पूर्णांक नहीं है और Trueयदि x एक पूर्णांक है, तो वापस आ जाता है।

मुझे नहीं पता कि यह पायथोनिक है, लेकिन यह एक पंक्ति है, और यह अपेक्षाकृत स्पष्ट है कि कोड क्या करता है।


कोशिश करो / छोड़कर किसी के लॉन पर चलने की तरह लगता है (कोशिश करें) और फिर अगर / जब वे नोटिस करते हैं और क्रोधित होते हैं (अपवाद) तो आप माफी मांगते हैं (अपवाद को संभालें), जबकि मेरा all(xi in '1234567890' for xi in x])पैटर्न अधिक लगता है जैसे लॉन में चलने की अनुमति मांगना । मैं एक अनुमति पूछने वाला होने के लिए रोमांचित नहीं हूं, लेकिन यहां हम हैं।
mRotten

3

मुझे लगता है

s.startswith('-') and s[1:].isdigit()

के लिए फिर से लिखना बेहतर होगा:

s.replace('-', '').isdigit()

क्योंकि s [1:] भी एक नया तार बनाता है

लेकिन ज्यादा बेहतर उपाय है

s.lstrip('+-').isdigit()

3
लगता है क्या replaceकरता है? इसके अलावा, यह गलत तरीके से स्वीकार करेगा 5-2, उदाहरण के लिए।
Ry-

एक IndexError फेंक देंगे अगरs='-'
एंटी पृथ्वी

s = '-'; s.replace ( '-', '') .isdigit () -> झूठी
Vladyslav Savchenko

2

मुझे वास्तव में शाविस की पोस्ट पसंद आई, लेकिन मैंने एक और टेस्ट केस जोड़ दिया (और बिल्ट इन इडीजित () फंक्शन):

def isInt_loop(v):
    v = str(v).strip()
    # swapping '0123456789' for '9876543210' makes nominal difference (might have because '1' is toward the beginning of the string)
    numbers = '0123456789'
    for i in v:
        if i not in numbers:
            return False
    return True

def isInt_Digit(v):
    v = str(v).strip()
    return v.isdigit()

और यह लगातार बाकी के समय को हराता है:

timings..
isInt_try:   0.4628
isInt_str:   0.3556
isInt_re:    0.4889
isInt_re2:   0.2726
isInt_loop:   0.1842
isInt_Digit:   0.1577

सामान्य 2.7 अजगर का उपयोग:

$ python --version
Python 2.7.10

मेरे द्वारा जोड़े गए दो परीक्षण मामले (isInt_loop और isInt_digit) सटीक एक ही परीक्षण के मामले पास करते हैं (वे दोनों केवल अहस्ताक्षरित पूर्णांक स्वीकार करते हैं), लेकिन मैंने सोचा था कि लोग स्ट्रिंग कार्यान्वयन (.Int_loop) को संशोधित करने के साथ और अधिक चतुर हो सकते हैं जो कि isdigit में निर्मित विरोध किया था () फ़ंक्शन, इसलिए मैंने इसे शामिल किया, भले ही निष्पादन समय में थोड़ा अंतर हो। (और दोनों तरीकों ने बाकी सभी चीजों को बहुत हरा दिया, लेकिन अतिरिक्त सामान को न संभालें: "./+//-"

इसके अलावा, मुझे यह नोट करना दिलचस्प लगा कि रेगेक्स (isInt_re2 विधि) ने उसी परीक्षण में स्ट्रिंग तुलना को हराया जो 2012 में शाविस द्वारा प्रदर्शन किया गया था (वर्तमान में 2018)। शायद रेगेक्स पुस्तकालयों में सुधार किया गया है?


1

यह शायद मेरी राय में इसे अप्रोच करने का सबसे सीधा और सरल तरीका है। मैंने इस समाधान को नहीं देखा और यह मूल रूप से रेगेक्स एक के समान है, लेकिन रेगेक्स के बिना।

def is_int(test):
    import string
    return not (set(test) - set(string.digits))

set(input_string) == set(string.digits)अगर हम छोड़ '-+ 'शुरुआत में और .0, E-1अंत में।
jfs

1

यहां एक फ़ंक्शन है जो त्रुटियों को बढ़ाए बिना पार्स करता है। यह Noneविफलता पर स्पष्ट मामलों के रिटर्न को संभालता है (CPython पर डिफ़ॉल्ट रूप से 2000 तक / - 'संकेतों को संभालता है!)।

#!/usr/bin/env python

def get_int(number):
    splits = number.split('.')
    if len(splits) > 2:
        # too many splits
        return None
    if len(splits) == 2 and splits[1]:
        # handle decimal part recursively :-)
        if get_int(splits[1]) != 0:
            return None

    int_part = splits[0].lstrip("+")
    if int_part.startswith('-'):
        # handle minus sign recursively :-)
        return get_int(int_part[1:]) * -1
    # successful 'and' returns last truth-y value (cast is always valid)
    return int_part.isdigit() and int(int_part)

कुछ परीक्षण:

tests = ["0", "0.0", "0.1", "1", "1.1", "1.0", "-1", "-1.1", "-1.0", "-0", "--0", "---3", '.3', '--3.', "+13", "+-1.00", "--+123", "-0.000"]

for t in tests:
    print "get_int(%s) = %s" % (t, get_int(str(t)))

परिणाम:

get_int(0) = 0
get_int(0.0) = 0
get_int(0.1) = None
get_int(1) = 1
get_int(1.1) = None
get_int(1.0) = 1
get_int(-1) = -1
get_int(-1.1) = None
get_int(-1.0) = -1
get_int(-0) = 0
get_int(--0) = 0
get_int(---3) = -3
get_int(.3) = None
get_int(--3.) = 3
get_int(+13) = 13
get_int(+-1.00) = -1
get_int(--+123) = 123
get_int(-0.000) = 0

अपनी आवश्यकताओं के लिए आप उपयोग कर सकते हैं:

def int_predicate(number):
     return get_int(number) is not None

1

मैं निम्नलिखित सुझाव देता हूं:

import ast

def is_int(s):
    return isinstance(ast.literal_eval(s), int)

से डॉक्स :

सुरक्षित रूप से एक अभिव्यक्ति नोड या एक पायथन शाब्दिक या कंटेनर डिस्प्ले युक्त स्ट्रिंग का मूल्यांकन करें। प्रदान की गई स्ट्रिंग या नोड में केवल निम्नलिखित पायथन शाब्दिक संरचनाएँ शामिल हो सकती हैं: स्ट्रिंग्स, बाइट्स, संख्याएँ, ट्यूपल्स, सूचियाँ, डीकट्स, सेट्स, बुलियन और कोई नहीं।

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

from ast import literal_eval
from contextlib import suppress

def is_int(s):
    with suppress(ValueError):
        return isinstance(literal_eval(s), int)
    return False

¯ \ _ (ツ) _ / ¯


0

मेरे पास एक संभावना है जो इंट का बिल्कुल भी उपयोग नहीं करता है, और एक अपवाद नहीं उठाना चाहिए जब तक कि स्ट्रिंग एक संख्या का प्रतिनिधित्व नहीं करती है

float(number)==float(number)//1

यह किसी भी प्रकार के स्ट्रिंग के लिए काम करना चाहिए जो फ्लोट स्वीकार करता है, सकारात्मक, नकारात्मक, इंजीनियरिंग संकेतन ...


0

मुझे लगता है कि इस सवाल का संबंध गति से है / इसके अलावा समय की सजा के अलावा:

 परीक्षण डेटा

सबसे पहले, मैंने 200 स्ट्रिंग्स, 100 असफल स्ट्रिंग्स और 100 संख्यात्मक स्ट्रिंग्स की एक सूची बनाई।

from random import shuffle
numbers = [u'+1'] * 100
nonumbers = [u'1abc'] * 100
testlist = numbers + nonumbers
shuffle(testlist)
testlist = np.array(testlist)

 खस्ता समाधान (केवल सरणियों और यूनिकोड के साथ काम करता है)

np.core.defchararray.isnumeric यूनिकोड स्ट्रिंग्स के साथ भी काम कर सकता है np.core.defchararray.isnumeric(u'+12')लेकिन यह रिटर्न और एरे देता है। तो, यह एक अच्छा समाधान है यदि आपको हजारों रूपांतरण करने हैं और लापता डेटा या गैर-संख्यात्मक डेटा है।

import numpy as np
%timeit np.core.defchararray.isnumeric(testlist)
10000 loops, best of 3: 27.9 µs per loop # 200 numbers per loop

कोशिश / छोड़कर

def check_num(s):
  try:
    int(s)
    return True
  except:
    return False

def check_list(l):
  return [check_num(e) for e in l]

%timeit check_list(testlist)
1000 loops, best of 3: 217 µs per loop # 200 numbers per loop

लगता है कि सुन्न समाधान बहुत तेज है।


0

यदि आप केवल लोअर-आस्की अंकों को स्वीकार करना चाहते हैं, तो यहां ऐसा करने के लिए परीक्षण हैं:

अजगर 3.7+: (u.isdecimal() and u.isascii())

अजगर <= 3.6: (u.isdecimal() and u == str(int(u)))

अन्य उत्तर का उपयोग करने का सुझाव देते हैं .isdigit()या .isdecimal()इन दोनों में कुछ ऊपरी-यूनिकोड वर्ण शामिल हैं जैसे '٢'( u'\u0662'):

u = u'\u0662'     # '٢'
u.isdigit()       # True
u.isdecimal()     # True
u.isascii()       # False (Python 3.7+ only)
u == str(int(u))  # False

यह नकारात्मक मानों या व्हाट्सएप्ड गद्देदार मूल्यों को संभाल नहीं पाएगा, दोनों को इसके द्वारा ही ठीक किया जाता है int()
शैडो रेंजर

-6

उह .. यह कोशिश करो:

def int_check(a):
    if int(a) == a:
        return True
    else:
        return False

यह काम करता है यदि आप एक स्ट्रिंग नहीं डालते हैं जो एक संख्या नहीं है।

और यह भी (मैं नंबर चेक भाग डालना भूल गया।), एक फ़ंक्शन जाँच रहा है कि क्या स्ट्रिंग एक संख्या है या नहीं। यह str.isdigit () है। यहाँ एक उदाहरण है:

a = 2
a.isdigit()

यदि आप a.isdigit () कहते हैं, तो यह True लौटेगा।


मुझे लगता है कि आपको दिए गए मान के आसपास उद्धरणों की आवश्यकता 2है a
ल्यूक वुडवर्ड

1
यह शीर्ष उत्तर क्यों नहीं है? यह प्रश्न का सटीक उत्तर देता है।
टिड्डा

6
-1 सवाल: "जाँच करें कि क्या एक स्ट्रिंग एक इंट का प्रतिनिधित्व करता है, बिना कोशिश / प्रयोग के?" @Caroline Alexiou के लिए
7
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.