มีวิธีที่จะบอกว่าใด ๆสตริงหมายถึงจํานวนเต็ม (เช่น'3'
, '-17'
แต่ไม่'3.14'
หรือ'asfasfas'
) โดยไม่ต้องใช้ลอง / ยกเว้นกลไก?
is_int('3.14') = False
is_int('-7') = True
มีวิธีที่จะบอกว่าใด ๆสตริงหมายถึงจํานวนเต็ม (เช่น'3'
, '-17'
แต่ไม่'3.14'
หรือ'asfasfas'
) โดยไม่ต้องใช้ลอง / ยกเว้นกลไก?
is_int('3.14') = False
is_int('-7') = True
คำตอบ:
หากคุณรำคาญใจกับการใช้งานtry/except
ทั่วสถานที่โปรดเขียนฟังก์ชันผู้ช่วย:
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
>>> print RepresentsInt("+123")
True
>>> print RepresentsInt("10.0")
False
มันจะเป็นรหัสเพิ่มเติมทางที่จะครอบคลุมสตริงทั้งหมดที่ Python พิจารณาว่าเป็นจำนวนเต็ม ฉันว่าเพียงแค่ pythonic กับอันนี้
>>> print RepresentsInt(10.0)
True
>>> print RepresentsInt(10.06)
True
ด้วยจำนวนเต็มบวกคุณสามารถใช้.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()
u'²'.isdigit()
เป็นจริง แต่int(u'²')
ก่อให้เกิด ValueError ใช้u.isdecimal()
แทน str.isdigit()
ขึ้นอยู่กับภาษาใน Python 2
check_int('')
จะเพิ่มข้อยกเว้นแทนการส่งคืนFalse
คุณรู้ว่าฉันได้พบ (และฉันได้ทดสอบสิ่งนี้ซ้ำแล้วซ้ำอีก) ที่ลอง / ยกเว้นทำงานได้ไม่ดีไม่ว่าด้วยเหตุผลใดก็ตาม ฉันมักจะลองทำหลายวิธีและฉันไม่คิดว่าฉันเคยพบวิธีที่ใช้ลอง / ยกเว้นเพื่อให้ได้ผลการทดสอบที่ดีที่สุดในความเป็นจริงดูเหมือนว่าสำหรับฉันแล้ววิธีการเหล่านั้นมักจะออกมาใกล้เคียงกับ เลวร้ายที่สุดถ้าไม่ใช่ที่เลวร้ายที่สุด ไม่ใช่ในทุกกรณี แต่ในหลายกรณี ฉันรู้ว่าผู้คนจำนวนมากพูดว่ามันเป็น "Pythonic" แต่นั่นเป็นพื้นที่หนึ่งที่ฉันมีส่วนร่วมกับพวกเขา สำหรับฉันมันไม่ได้มีประสิทธิภาพมากนักหรือสง่างามมากดังนั้นฉันมักจะใช้เพื่อดักจับและรายงานข้อผิดพลาดเท่านั้น
ฉันจะจับ PHP, perl, ruby, C และแม้แต่ shell ที่ผิดปกติมีฟังก์ชั่นที่ง่ายสำหรับการทดสอบสตริงสำหรับเลขจำนวนเต็ม - hood แต่เนื่องจากความขยันในการตรวจสอบสมมติฐานเหล่านั้นทำให้ฉันสะดุด! เห็นได้ชัดว่าการขาดนี้เป็นโรคทั่วไป
นี่คือการแก้ไขโพสต์ของ Bruno ที่รวดเร็วและสกปรก:
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
วิธีการ AC สามารถสแกนมันทีละครั้งและทำได้ ฉันคิดว่าวิธี AC ที่สแกนสตริงครั้งเดียวจะเป็นสิ่งที่ถูกต้อง
แก้ไข:
ฉันได้อัปเดตโค้ดข้างต้นเพื่อให้ทำงานใน Python 3.5 และรวมฟังก์ชัน check_int จากคำตอบที่ได้รับการโหวตมากที่สุดในปัจจุบันและใช้ regex ที่เป็นที่นิยมที่สุดในปัจจุบันที่ฉันสามารถค้นหาเพื่อทดสอบเลขจำนวนเต็ม regex นี้ปฏิเสธสตริงเช่น 'abc 123' ฉันได้เพิ่ม 'abc 123' เป็นค่าทดสอบ
เป็นสิ่งที่น่าสนใจอย่างยิ่งสำหรับฉันที่จะต้องทราบ ณ จุดนี้ว่าไม่มีฟังก์ชั่นที่ทดสอบรวมถึงวิธีลองฟังก์ชั่น check_int ยอดนิยมและ regex ที่นิยมที่สุดสำหรับการทดสอบเลขจำนวนเต็มกลับคำตอบที่ถูกต้องสำหรับทุก ค่าทดสอบ (ดีขึ้นอยู่กับสิ่งที่คุณคิดว่าคำตอบที่ถูกต้องคือดูผลการทดสอบด้านล่าง)
ฟังก์ชั่น int () ฟังก์ชั่นตัดส่วนเศษส่วนของจำนวนจุดลอยตัวและส่งกลับส่วนจำนวนเต็มก่อนทศนิยมยกเว้นในกรณีที่ตัวเลขจุดลอยตัวจะถูกแปลงเป็นสตริงแรก
ฟังก์ชัน check_int () ส่งคืนค่าเท็จสำหรับค่าเช่น 0.0 และ 1.0 (ซึ่งทางเทคนิคเป็นจำนวนเต็ม) และส่งคืนค่าจริงสำหรับค่าเช่น '06'
นี่คือผลการทดสอบปัจจุบัน (Python 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. และ .0 เป็นต้น แต่มันก็ให้ผลตอบแทนจริงสำหรับ '06' เช่นกัน เลือกพิษของคุณฉันเดา
try
มีประสิทธิภาพมากขึ้น: isInt_try: 0.6552 / isInt_str: 0.6396 / isInt_re: 1.0296 / isInt_re2: 0.5168
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
ใช้นิพจน์ทั่วไป:
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()
เพื่อประสิทธิภาพที่ดีขึ้นถ้าคุณกำลังทำเช่นนี้มักจะรวบรวมการแสดงออกปกติใช้เพียงครั้งเดียว
โซลูชัน RegEx ที่เหมาะสมจะรวมแนวคิดของ Greg Hewgill และ Nowell แต่ไม่ใช้ตัวแปรส่วนกลาง คุณสามารถทำได้โดยแนบคุณสมบัติกับวิธีการ นอกจากนี้ฉันรู้ว่ามันขมวดคิ้วที่จะนำเข้าในวิธีการ แต่สิ่งที่ฉันจะเป็นผล "โมดูลขี้เกียจ" เช่นhttp://peak.telecommunity.com/DevCenter/Importing#lazy-imports
แก้ไข:เทคนิคที่ฉันชื่นชอบจนถึงตอนนี้คือการใช้วิธีการเฉพาะของวัตถุ String
#!/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
>>> "+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()
วิธีการของ Greg Hewgill หายไปจากองค์ประกอบบางส่วน: "^" นำหน้าเพื่อให้ตรงกับจุดเริ่มต้นของสตริงและรวบรวมอีกครั้งก่อน แต่วิธีการนี้จะช่วยให้คุณหลีกเลี่ยงการลอง: exept:
import re
INT_RE = re.compile(r"^[-]?\d+$")
def RepresentsInt(s):
return INT_RE.match(str(s)) is not None
ฉันสนใจว่าทำไมคุณถึงพยายามหลีกเลี่ยง: ยกเว้น?
ฉันต้องทำเช่นนี้ตลอดเวลาและฉันมีความเกลียดชังที่ไม่รุนแรง แต่ไม่เป็นที่ยอมรับในการใช้รูปแบบลอง / ยกเว้น ฉันใช้สิ่งนี้:
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)])
มีอย่างน้อยสองกรณี (ขอบ?) ซึ่งสิ่งนี้แตกสลาย:
type(1E2)
จะช่วยให้<class 'float'>
ในขณะที่ช่วยให้type(10^2)
<class 'int'>
ดังนั้นจะไม่ทำงานสำหรับทุกอินพุตที่เป็นไปได้ แต่ถ้าคุณสามารถยกเว้นเครื่องหมายทางวิทยาศาสตร์, สัญลักษณ์เอ็กซ์โพเนนเชียลและสตริงว่างมันเป็นการตรวจสอบหนึ่งบรรทัดที่ตกลงว่าส่งคืนFalse
ถ้า x ไม่ใช่จำนวนเต็มและTrue
ถ้า x เป็นจำนวนเต็ม
ฉันไม่รู้ว่ามันเป็น pythonic หรือไม่ แต่เป็นหนึ่งบรรทัดและค่อนข้างชัดเจนว่าโค้ดทำอะไร
all(xi in '1234567890' for xi in x])
รูปแบบของฉันดูเหมือนจะขออนุญาตให้เดินข้ามสนามหญ้า ฉันไม่ได้ตื่นเต้นที่ได้เป็นผู้ขออนุญาต แต่เราอยู่ที่นี่
ฉันคิด
s.startswith('-') and s[1:].isdigit()
จะดีกว่าถ้าเขียนใหม่เป็น:
s.replace('-', '').isdigit()
เพราะ s [1:] ยังสร้างสตริงใหม่
แต่ทางออกที่ดีกว่าก็คือ
s.lstrip('+-').isdigit()
replace
ทำ เช่นนี้จะยอมรับอย่างไม่ถูกต้อง5-2
เช่น
s='-'
ฉันชอบโพสต์ของ Shavais จริงๆ แต่ฉันได้เพิ่มอีกหนึ่งกรณีทดสอบ (& ฟังก์ชัน isdigit () ในตัว):
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) ผ่านกรณีทดสอบเดียวกันที่แน่นอน (ทั้งคู่ยอมรับเฉพาะจำนวนเต็มที่ไม่ได้ลงนาม) แต่ฉันคิดว่าผู้คนจะฉลาดกว่าด้วยการปรับเปลี่ยนการใช้สตริง (isInt_loop) ตรงข้ามกับ built in isdigit () ฟังก์ชั่นดังนั้นฉันจึงรวมไว้แม้ว่าจะมีความแตกต่างเล็กน้อยในเวลาดำเนินการ (และทั้งสองวิธีเอาชนะทุกอย่างเป็นอย่างมาก แต่อย่าจัดการกับสิ่งพิเศษ: "./+/-")
นอกจากนี้ฉันพบว่ามันน่าสนใจที่จะทราบว่า regex (isInt_re2 วิธี) เอาชนะการเปรียบเทียบสตริงในการทดสอบเดียวกันที่ดำเนินการโดย Shavais ในปี 2012 (ปัจจุบัน 2018) อาจปรับปรุงไลบรารี regex หรือไม่
นี่อาจเป็นวิธีที่ตรงไปตรงมาและไพเราะที่สุดในความคิดของฉัน ฉันไม่เห็นวิธีแก้ปัญหานี้และมันก็เหมือนกับ regex แต่ไม่มี regex
def is_int(test):
import string
return not (set(test) - set(string.digits))
set(input_string) == set(string.digits)
ถ้าเราข้ามไป'-+ '
ที่จุดเริ่มต้นและ.0
, E-1
ในตอนท้าย
นี่คือฟังก์ชันที่แยกวิเคราะห์โดยไม่เพิ่มข้อผิดพลาด มันจัดการกรณีที่เห็นได้ชัดผลตอบแทนNone
จากความล้มเหลว (จัดการได้ถึง 2000 '- / +' สัญญาณตามค่าเริ่มต้นใน CPython!):
#!/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
ฉันขอแนะนำดังต่อไปนี้:
import ast
def is_int(s):
return isinstance(ast.literal_eval(s), int)
จากเอกสาร :
ประเมินโหนดนิพจน์หรือสตริงที่มีการแสดงตัวอักษรหรือคอนเทนเนอร์ของ Python อย่างปลอดภัย สตริงหรือโหนดที่ระบุอาจประกอบด้วยโครงสร้างตัวอักษร Python ดังต่อไปนี้เท่านั้น: สตริง, ไบต์, ตัวเลข, สิ่งอันดับ, รายการ, dicts, ชุด, booleans และไม่มี
ฉันควรทราบว่าสิ่งนี้จะทำให้เกิดValueError
ข้อยกเว้นเมื่อมีการเรียกร้องสิ่งใดก็ตามที่ไม่ได้เป็นตัวอักษร Python เนื่องจากคำถามถามหาทางออกโดยไม่ลอง / ยกเว้นฉันมีวิธีแก้ปัญหาแบบ Kobayashi-Maru สำหรับสิ่งนั้น:
from ast import literal_eval
from contextlib import suppress
def is_int(s):
with suppress(ValueError):
return isinstance(literal_eval(s), int)
return False
¯ \ _ (ツ) _ / ¯
ฉันมีความเป็นไปได้หนึ่งอย่างที่ไม่ได้ใช้ int เลยและไม่ควรเพิ่มข้อยกเว้นเว้นแต่สตริงจะไม่แสดงตัวเลข
float(number)==float(number)//1
มันควรใช้กับสตริงชนิดใดก็ได้ที่ลอยยอมรับ, เป็นลบ, เป็นเครื่องหมายทางวิศวกรรม ...
ฉันเดาว่าคำถามนั้นเกี่ยวข้องกับความเร็วตั้งแต่การลอง / ยกเว้นมีการปรับเวลา:
ก่อนอื่นฉันสร้างรายการ 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 ยังสามารถทำงานกับสตริง unicode ได้np.core.defchararray.isnumeric(u'+12')
แต่มันจะส่งคืนและเรียงลำดับ ดังนั้นจึงเป็นทางออกที่ดีหากคุณต้องทำหลายพัน Conversion และไม่มีข้อมูลหรือข้อมูลที่ไม่ใช่ตัวเลข
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
ดูเหมือนว่าวิธีแก้ปัญหาแบบ numpy นั้นเร็วกว่ามาก
หากคุณต้องการที่จะยอมรับตัวเลขที่ต่ำกว่า ascii เท่านั้นนี่คือการทดสอบที่จะทำ:
Python 3.7+: (u.isdecimal() and u.isascii())
Python <= 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()
ซึ่งทั้งสองได้รับการจัดการโดยเพียงแค่ปรับ
เอ่อ .. ลองดูสิ:
def int_check(a):
if int(a) == a:
return True
else:
return False
วิธีนี้ใช้ได้ผลถ้าคุณไม่ใส่สตริงที่ไม่ใช่ตัวเลข
และ (ฉันลืมใส่ส่วนตรวจสอบตัวเลข) มีฟังก์ชั่นตรวจสอบว่าสตริงเป็นตัวเลขหรือไม่ มันคือ str.isdigit () นี่คือตัวอย่าง:
a = 2
a.isdigit()
หากคุณโทร a.isdigit () ระบบจะส่งคืน True
2
a