2013-03-12 9 views
10

में परिवर्तित किया जाना चाहिए, मैं एक स्ट्रिंग को सबसे कठिन संभव डेटाटाइप में परिवर्तित करना चाहता हूं: int या float।पायथन, निर्धारित करें कि एक स्ट्रिंग को Int या Float

मैं दो तार है:

value1="0.80"  #this needs to be a float 
value2="1.00"  #this needs to be an integer. 

मैं कैसे तय कर सकते हैं कि मान 1 फ्लोट किया जाना चाहिए और मान 2 अजगर में पूर्णांक होना चाहिए?

उत्तर

20
def isfloat(x): 
    try: 
     a = float(x) 
    except ValueError: 
     return False 
    else: 
     return True 

def isint(x): 
    try: 
     a = float(x) 
     b = int(a) 
    except ValueError: 
     return False 
    else: 
     return a == b 
+2

बेशक, किसी को 'isint()' पहले परीक्षण करना चाहिए, और उसके बाद 'isfloat()' के लिए परीक्षण करना चाहिए, यदि पूर्व रिटर्न 'गलत' है। –

+0

अच्छी तरह से पहले आइसेंट का प्रयास करें, और उसके बाद isfloat का उपयोग करें, लेकिन, अगर मैं isint का उपयोग करता हूं तो सभी परीक्षण पास हो जाते हैं। क्या आपको लगता है कि बेहतर उपयोग isint() केवल है? – ManuParra

+1

यह बहुत बड़ी संख्या के लिए गलत है। उदाहरण के लिए, फ्लोट ("10000000000000000.5") 1e + 16 है, int (1e + 16) 1e + 16 है, फिर भी संख्या int नहीं है। – Nixon

12

अजगर float वस्तुओं एक is_integer method है:

from ast import literal_eval 
def parses_to_integer(s): 
    val = literal_eval(s) 
    return isinstance(val, int) or (isinstance(val, float) and val.is_integer()) 
+0

मैं इस विधि को पसंद करता हूं क्योंकि यह मूल्यांकन के एक हिस्से के रूप में अपवाद पर भरोसा नहीं करता है। – DaveL17

+0

यदि एस वैध साक्षरता का मूल्यांकन नहीं करता है तो यह एक त्रुटि फेंक देगा। इसके अलावा 'गलत' एक पूर्णांक के रूप में वापस आ जाएगा जो शायद आप नहीं चाहते हैं। मुझे पता है कि आप सीधे उपयोगकर्ता के प्रश्न का उत्तर दे रहे हैं ताकि आप समाधान मान्य हो लेकिन किसी भी माउस जाल में सुधार किया जा सके। – shrewmouse

3
def coerce(x): 
    try: 
     a = float(x) 
     b = int(x) 
     if a == b: 
      return b 
     else: 
      return a 
    except: 
     raise ValueError("failed to coerce str to int or float") 
+0

यह फ्लोट के लिए असफल हो जाएगा। यदि 'x == 0.5', पंक्ति 'बी = int (x)' एक ValueError अपवाद तुरंत फेंक देगा और' अगर एक == बी 'सशर्त कभी नहीं किया जाएगा। – daveruinseverything

0

मैं यह सुनिश्चित करना कि '1.0' '1' में परिवर्तित हो जाता है जब मैं मतभेद निर्धारित करने के लिए कोशिश कर रहा था के मामले को संभालने के लिए किया था दो एक्सएमएल दस्तावेज़ों के बीच। इसलिए मैंने इस काम को मेरी मदद करने के लिए लिखा। मुझे यह भी लगता है कि कुछ अन्य समाधान विफल हो जाएंगे जब प्रश्न में शाब्दिक स्ट्रिंग 'ट्रू' या 'गलत' है। किसी भी दर पर यह समारोह मेरे लिए बहुत अच्छा काम करता है। मुझे उम्मीद है कि यह आपकी भी मदद करेगा।

from ast import literal_eval 

def convertString(s): 
    ''' 
    This function will try to convert a string literal to a number or a bool 
    such that '1.0' and '1' will both return 1. 

    The point of this is to ensure that '1.0' and '1' return as int(1) and that 
    'False' and 'True' are returned as bools not numbers. 

    This is useful for generating text that may contain numbers for diff 
    purposes. For example you may want to dump two XML documents to text files 
    then do a diff. In this case you would want <blah value='1.0'/> to match 
    <blah value='1'/>. 

    The solution for me is to convert the 1.0 to 1 so that diff doesn't see a 
    difference. 

    If s doesn't evaluate to a literal then s will simply be returned UNLESS the 
    literal is a float with no fractional part. (i.e. 1.0 will become 1) 

    If s evaluates to float or a float literal (i.e. '1.1') then a float will be 
    returned if and only if the float has no fractional part. 

    if s evaluates as a valid literal then the literal will be returned. (e.g. 
    '1' will become 1 and 'False' will become False) 
    ''' 


    if isinstance(s, str): 
     # It's a string. Does it represnt a literal? 
     # 
     try: 
      val = literal_eval(s) 
     except: 
      # s doesn't represnt any sort of literal so no conversion will be 
      # done. 
      # 
      val = s 
    else: 
     # It's already something other than a string 
     # 
     val = s 

    ## 
    # Is the float actually an int? (i.e. is the float 1.0 ?) 
    # 
    if isinstance(val, float): 
     if val.is_integer(): 
      return int(val) 

     # It really is a float 
     return val 

    return val 

इस समारोह की इकाई परीक्षण के उत्पादन का उत्पादन:

convertString("1")=1; we expect 1 
convertString("1.0")=1; we expect 1 
convertString("1.1")=1.1; we expect 1.1 
convertString("010")=8; we expect 8 
convertString("0xDEADBEEF")=3735928559; we expect 3735928559 
convertString("hello")="hello"; we expect "hello" 
convertString("false")="false"; we expect "false" 
convertString("true")="true"; we expect "true" 
convertString("False")=False; we expect False 
convertString("True")=True; we expect True 
convertString(sri.gui3.xmlSamples.test_convertString.A)=sri.gui3.xmlSamples.test_convertString.A; we expect sri.gui3.xmlSamples.test_convertString.A 
convertString(<function B at 0x7fd9e2f27ed8>)=<function B at 0x7fd9e2f27ed8>; we expect <function B at 0x7fd9e2f27ed8> 
convertString(1)=1; we expect 1 
convertString(1.0)=1; we expect 1 
convertString(1.1)=1.1; we expect 1.1 
convertString(3735928559)=3735928559; we expect 3735928559 
convertString(False)=False; we expect False 
convertString(True)=True; we expect True 

इकाई परीक्षण कोड इस प्रकार है:

import unittest 

# just class for testing that the class gets returned unmolested. 
# 
class A: pass 

# Just a function 
# 
def B(): pass 

class Test(unittest.TestCase): 


    def setUp(self): 
     self.conversions = [ 
      # input  | expected 
      ('1'   ,1  ), 
      ('1.0'  ,1  ), # float with no fractional part 
      ('1.1'  ,1.1  ), 
      ('010'  ,8  ), # octal 
      ('0xDEADBEEF',0xDEADBEEF), # hex 
      ('hello'  ,'hello' ), 
      ('false'  ,'false' ), 
      ('true'  ,'true' ), 
      ('False'  ,False ), # bool 
      ('True'  ,True  ), # bool 
      (A   ,A  ), # class 
      (B   ,B  ), # function 
      (1   ,1  ), 
      (1.0   ,1  ), # float with no fractional part 
      (1.1   ,1.1  ), 
      (0xDEADBEEF ,0xDEADBEEF), 
      (False  ,False ), 
      (True  ,True  ), 
     ] 


    def testName(self): 
     for s,expected in self.conversions: 
      rval = convertString(s) 
      print 'convertString({s})={rval}; we expect {expected}'.format(**locals()) 
      self.assertEqual(rval, expected) 


if __name__ == "__main__": 
    #import sys;sys.argv = ['', 'Test.testName'] 
    unittest.main() 
0

यहाँ eval() का उपयोग कर एक दिलचस्प समाधान है। नोट: eval का उपयोग करना अत्यधिक खतरनाक है और उत्पादन वातावरण में कहीं भी अनुशंसित नहीं है या कहीं भी eval() उपयोगकर्ता इनपुट प्राप्त कर सकता है! इसे केवल एक अकादमिक रूप से दिलचस्प जवाब पर विचार करें।

def get_string_type(x): 
    if type(x) != str: 
     raise ValueError('Input must be a string!') 
    try: 
     string_type = type(eval(x)) 
    except NameError: 
     string_type = str 
    return string_type 

के बाद से Eval कच्चे कोड के रूप में स्ट्रिंग व्यवहार करता है, यह किसी भी प्रकार आप एक repl में प्रवेश कर सकते के लिए काम करता है। उदाहरण

>>> from decimal import Decimal 
>>> my_test_string = 'Decimal(0.5)' 
>>> type(my_test_string) 
<class 'str'> 
>>> get_string_type(my_test_string) 
<class 'decimal.Decimal'> 
संबंधित मुद्दे