Làm cách nào để kiểm tra xem một chuỗi có phải là số (float) không?


1609

Cách tốt nhất có thể để kiểm tra xem một chuỗi có thể được biểu diễn dưới dạng số trong Python không?

Chức năng tôi hiện có ngay bây giờ là:

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

Mà, không chỉ xấu xí và chậm chạp, có vẻ vụng về. Tuy nhiên tôi đã không tìm thấy một phương pháp tốt hơn bởi vì gọi floatchức năng chính thậm chí còn tồi tệ hơn.


61
Có gì sai với giải pháp hiện tại của bạn? Nó ngắn, nhanh và dễ đọc.
Đại tá Panic

5
Và bạn không cần phải trả về Đúng hay Sai. Thay vào đó, bạn có thể trả về giá trị được sửa đổi phù hợp - ví dụ: bạn có thể sử dụng giá trị này để đặt các số không trong dấu ngoặc kép.
Thruston

7
Sẽ không tốt hơn để trả lại kết quả của float (s) trong trường hợp chuyển đổi thành công? Bạn vẫn có kiểm tra thành công (kết quả là Sai) và bạn thực sự CÓ chuyển đổi, dù sao bạn cũng có thể muốn.
Jiminion

8
Mặc dù câu hỏi này đã cũ hơn, tôi chỉ muốn nói rằng đây là một cách thanh lịch được ghi nhận là EAFP . Vì vậy, có lẽ là giải pháp tốt nhất cho loại vấn đề này.
thiruvenkadam

7
Không trả lại kết quả của float (s) hoặc Không có lỗi. nếu sau đó bạn sử dụng nó như x = float('0.00'); if x: use_float(x);bây giờ bạn đã có một lỗi trong mã của bạn. Giá trị thật là lý do các hàm này đưa ra một ngoại lệ thay vì quay lại Noneở vị trí đầu tiên. Một giải pháp tốt hơn là chỉ cần tránh chức năng tiện ích và bao quanh cuộc gọi để nổi try catchkhi bạn muốn sử dụng nó.
ovangle

Câu trả lời:


699

Mà, không chỉ xấu và chậm

Tôi sẽ tranh chấp cả hai.

Một regex hoặc phương pháp phân tích chuỗi khác sẽ xấu hơn và chậm hơn.

Tôi không chắc chắn rằng bất cứ điều gì nhiều có thể nhanh hơn ở trên. Nó gọi hàm và trả về. Thử / Bắt không giới thiệu nhiều chi phí vì ngoại lệ phổ biến nhất được bắt mà không cần tìm kiếm rộng rãi các khung ngăn xếp.

Vấn đề là bất kỳ hàm chuyển đổi số nào cũng có hai loại kết quả

  • Một số, nếu số đó hợp lệ
  • Mã trạng thái (ví dụ: qua errno) hoặc ngoại lệ để cho thấy rằng không có số hợp lệ nào có thể được phân tích cú pháp.

C (như một ví dụ) hack xung quanh điều này một số cách. Python đặt nó rõ ràng và rõ ràng.

Tôi nghĩ rằng mã của bạn để làm điều này là hoàn hảo.


21
Tôi không nghĩ rằng mã là hoàn hảo (nhưng tôi nghĩ rằng nó rất gần): nó là bình thường hơn để đưa chỉ một phần được "thử nghiệm" trong trykhoản, vì vậy tôi sẽ đặt return Truetrong một elsekhoản của try. Một trong những lý do là với mã trong câu hỏi, nếu tôi phải xem lại nó, tôi sẽ phải kiểm tra xem câu lệnh thứ hai trong trymệnh đề không thể tăng ValueError: được cấp, điều này không đòi hỏi quá nhiều thời gian hoặc sức mạnh não bộ, Nhưng tại sao sử dụng bất kỳ khi không cần thiết?
Eric O Lebigot

4
Câu trả lời có vẻ hấp dẫn, nhưng khiến tôi tự hỏi tại sao nó không được cung cấp ngoài lề ... Tôi sẽ sao chép nó và sử dụng nó trong mọi trường hợp.
hiền nhân

9
Thật tồi tệ. Làm thế nào về nếu tôi không quan tâm những gì số chỉ rằng đó là một số (đó là những gì mang lại cho tôi ở đây)? Thay vì 1 dòng IsNumeric()tôi kết thúc bằng thử / bắt hoặc gói khác thử / bắt. Ugh
Cơ bản

6
Nó không được cung cấp 'ngoài hộp' vì if is_number(s): x = float(x) else: // failcó cùng số dòng mã như try: x = float(x) catch TypeError: # fail. Chức năng tiện ích này là một sự trừu tượng hoàn toàn không cần thiết.
ovangle

12
Nhưng trừu tượng là toàn bộ điểm của các thư viện. Có chức năng 'isNumber' (bằng bất kỳ ngôn ngữ nào) sẽ giúp ích rất nhiều vì bạn có thể xây dựng nó thành các câu lệnh if và có mã dễ đọc và dễ bảo trì hơn, dựa vào các khối bắt thử. Ngoài ra, nếu bạn cần sử dụng mã nhiều lần trong nhiều hơn một lớp / mô-đun, thì bạn đã sử dụng nhiều dòng mã hơn so với chức năng tích hợp sẵn.
JamEngulfer 18/03/2016

1612

Trong trường hợp bạn đang tìm kiếm các số nguyên phân tích (dương, không dấu) thay vì số float, bạn có thể sử dụng isdigit()hàm cho các đối tượng chuỗi.

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False

Các phương thức chuỗi - isdigit(): Python2 , Python3

Ngoài ra còn có một số thứ trên chuỗi Unicode, mà tôi không quá quen thuộc với Unicode - Là số thập phân / thập phân


232
Đó cũng là một tiêu cực về tiêu cực
thay đổi vào

22
Thất bại với số mũ quá: '1e3'. Thẩm quyền () -> Sai
ssc

35
Trong khi Number! = Digit, những người đang tìm cách kiểm tra xem một chuỗi có chứa một số nguyên có thể rất hay vấp phải câu hỏi này hay không, và cách tiếp cận isDigit có thể rất phù hợp cho ứng dụng của họ.
Adam Parkin

8
@AdamParkin: isdigit()int()có ý kiến khác nhau về những gì là một số nguyên ví dụ, đối với các ký tự Unicode u'\u00b9': u'¹'.isdigit()Truenhưng int(u'¹')tăng ValueError.
jfs

6
+1: isdigit () có thể không phải là thứ mà OP đang tìm kiếm, nhưng đó chính xác là những gì tôi muốn. Nó có thể không phải là trường hợp câu trả lời và phương pháp này không bao gồm tất cả các loại số, nhưng nó vẫn có liên quan cao, trái với các lập luận về độ chính xác của nó. Trong khi "Số! = Chữ số", chữ số vẫn là tập con của số, đặc biệt là các số dương, không âm và sử dụng cơ sở 1-10. Hơn nữa, phương pháp này đặc biệt hữu ích và ngắn gọn cho các trường hợp bạn muốn kiểm tra xem một chuỗi có phải là ID số hay không, thường rơi vào tập hợp con số mà tôi vừa mô tả.
Justin Johnson

161

TL; DR Giải pháp tốt nhất làs.replace('.','',1).isdigit()

Tôi đã làm một số điểm chuẩn so sánh các phương pháp khác nhau

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

import re    
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re.match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

Nếu chuỗi không phải là một số, khối ngoại trừ khá chậm. Nhưng quan trọng hơn, phương pháp thử ngoại trừ là phương pháp duy nhất xử lý các ký hiệu khoa học một cách chính xác.

funcs = [
          is_number_tryexcept, 
          is_number_regex,
          is_number_repl_isdigit
          ]

a_float = '.1234'

print('Float notation ".1234" is not supported by:')
for f in funcs:
    if not f(a_float):
        print('\t -', f.__name__)

Ký hiệu nổi ".1234" không được hỗ trợ bởi:
- is_number_regex

scientific1 = '1.000000e+50'
scientific2 = '1e50'


print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
    if not f(scientific1):
        print('\t -', f.__name__)




print('Scientific notation "1e50" is not supported by:')
for f in funcs:
    if not f(scientific2):
        print('\t -', f.__name__)

Ký hiệu khoa học "1.000000e + 50" không được hỗ trợ bởi:
- is_number_regex
- is_number_Vpl_itorigit
Ký hiệu khoa học "1e50" không được hỗ trợ bởi:
- is_number_regex
- is_number_Vpl_ thẩmigit

EDIT: Kết quả điểm chuẩn

import timeit

test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}

for t in test_cases:
    for f in funcs:
        f = f.__name__
        times_n[f].append(min(timeit.Timer('%s(t)' %f, 
                      'from __main__ import %s, t' %f)
                              .repeat(repeat=3, number=1000000)))

nơi các chức năng sau đã được thử nghiệm

from re import match as re_match
from re import compile as re_compile

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True is string is a number. """
    if re_match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


comp = re_compile("^\d+?\.\d+?$")    

def compiled_regex(s):
    """ Returns True is string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

nhập mô tả hình ảnh ở đây


15
cho biểu đồ đẹp +1. Tôi đã nhìn thấy điểm chuẩn và biểu đồ đã thấy, tất cả điều TL; DR trở nên rõ ràng và trực quan.
jcchuks

Tôi đồng ý với @JCChuks: biểu đồ giúp rất nhiều để có được tất cả TL; DR một cách nhanh chóng. Nhưng tôi nghĩ rằng một TL; DR (như: TL; DR : giải pháp tốt nhất là s.replace('.','',1).isdigit()) sẽ xuất hiện ở đầu của anwser này. Trong mọi trường hợp, nó phải là một trong những chấp nhận. Cảm ơn!
Simon C.

10
Phương pháp này không xử lý số âm (dấu gạch ngang). Tôi sẽ ủng hộ việc chỉ sử dụng phương pháp float vì nó ít bị lỗi và sẽ hoạt động mọi lúc.
Urchin

3
Điều quan trọng cần lưu ý là ngay cả trên giả định không thể có dấu gạch ngang, phương pháp thay thế số chỉ nhanh hơn đối với các số không (kết quả sai), trong khi phương pháp thử ngoại trừ nhanh hơn cho các số (Kết quả đúng). Nếu hầu hết đầu vào của bạn là đầu vào hợp lệ, tốt hơn hết bạn nên sử dụng giải pháp ngoại trừ thử!
Markus von Broady

1
Không hoạt động trên ký hiệu số mũ như '1.5e-9'hoặc trên phủ định.
EL_DON

68

Có một ngoại lệ mà bạn có thể muốn tính đến: chuỗi 'NaN'

Nếu bạn muốn is_number trả về FALSE cho 'NaN', mã này sẽ không hoạt động vì Python chuyển đổi nó thành đại diện của một số không phải là số (nói về các vấn đề nhận dạng):

>>> float('NaN')
nan

Nếu không, tôi thực sự nên cảm ơn bạn về đoạn mã mà bây giờ tôi sử dụng rộng rãi. :)

G.


2
Trên thực tế, NaNcó thể là một giá trị tốt để trả về (chứ không phải False) nếu văn bản được truyền không thực sự là một đại diện của một số. Kiểm tra xem nó có phải là một nỗi đau không ( floatloại của Python thực sự cần một phương pháp cho nó) nhưng bạn có thể sử dụng nó trong các phép tính mà không tạo ra lỗi và chỉ cần kiểm tra kết quả.
chào

7
Một ngoại lệ khác là chuỗi 'inf'. Hoặc infhoặc NaNcũng có thể được bắt đầu bằng một +hoặc -và vẫn được chấp nhận.
agf

4
Nếu bạn muốn trả về Sai cho NaN và Inf, hãy đổi dòng thành x = float (s); trả về (x == x) và (x - 1! = x). Điều này sẽ trả về True cho tất cả các số float trừ Inf và NaN
RyanN 15/03/13

5
x-1 == xlà đúng cho phao lớn nhỏ hơn inf. Từ Python 3.2, bạn có thể sử dụng math.isfiniteđể kiểm tra các số không phải là NaN hay vô hạn hoặc kiểm tra cả hai math.isnanmath.isinftrước đó.
Steve Jessop

56

Còn cái này thì sao:

'3.14'.replace('.','',1).isdigit()

sẽ chỉ trả về đúng nếu có một hoặc không '.' trong chuỗi các chữ số.

'3.14.5'.replace('.','',1).isdigit()

sẽ trả lại sai

chỉnh sửa: chỉ cần thấy một bình luận khác ... thêm một .replace(badstuff,'',maxnum_badstuff)cho các trường hợp khác có thể được thực hiện. nếu bạn chuyển muối và không gia vị tùy ý (ref: xkcd # 974 ) thì điều này sẽ làm tốt: P


7
Tuy nhiên, điều này không chiếm số âm.
Michael Barton

5
Hoặc các số có số mũ như 1.234e56(cũng có thể được viết dưới dạng +1.234E+56và một số biến thể khác).
Alfe

re.match(r'^[+-]*(0[xbo])?[0-9A-Fa-f]*\.?[0-9A-Fa-f]*(E[+-]*[0-9A-Fa-f]+)$', 'str')nên làm tốt hơn việc xác định một số (nhưng không phải tất cả, tôi không khẳng định điều đó). Tôi không khuyên bạn nên sử dụng mã này, tốt hơn nhiều để sử dụng mã gốc của Người hỏi.
Baldrickk

nếu bạn không thích giải pháp này, hãy đọc trước khi tải xuống!
aloisdg chuyển đến codidact.com

Người đàn ông này là giải pháp thông minh nhất tôi từng thấy trong trang web này!, người đàn ông thực hiện tốt!
Karam Qusai

41

Mà, không chỉ xấu xí và chậm chạp, có vẻ vụng về.

Nó có thể mất một số quen thuộc, nhưng đây là cách làm pythonic. Như đã được chỉ ra, các lựa chọn thay thế là tồi tệ hơn. Nhưng có một lợi thế khác của việc làm theo cách này: đa hình.

Ý tưởng trung tâm đằng sau việc gõ vịt là "nếu nó đi lại và nói chuyện như một con vịt, thì đó là một con vịt". Điều gì sẽ xảy ra nếu bạn quyết định rằng bạn cần phải phân lớp chuỗi để bạn có thể thay đổi cách xác định xem có thể chuyển đổi thành thứ gì đó không Hoặc nếu bạn quyết định kiểm tra một số đối tượng khác hoàn toàn thì sao? Bạn có thể làm những điều này mà không phải thay đổi mã trên.

Các ngôn ngữ khác giải quyết những vấn đề này bằng cách sử dụng giao diện. Tôi sẽ lưu phân tích về giải pháp nào tốt hơn cho chủ đề khác. Mặc dù vậy, vấn đề là con trăn quyết định ở bên gõ vịt của phương trình và có lẽ bạn sẽ phải làm quen với cú pháp như thế này nếu bạn dự định thực hiện nhiều chương trình trong Python (nhưng điều đó không có nghĩa bạn phải thích nó tất nhiên).

Một điều khác mà bạn có thể muốn xem xét: Python khá nhanh trong việc ném và bắt ngoại lệ so với rất nhiều ngôn ngữ khác (nhanh hơn 30 lần so với .Net chẳng hạn). Heck, bản thân ngôn ngữ thậm chí còn ném ngoại lệ để giao tiếp các điều kiện chương trình bình thường, không đặc biệt (mỗi khi bạn sử dụng vòng lặp for). Vì vậy, tôi sẽ không lo lắng quá nhiều về các khía cạnh hiệu suất của mã này cho đến khi bạn nhận thấy một vấn đề quan trọng.


1
Một nơi phổ biến khác mà Python sử dụng ngoại lệ cho các hàm cơ bản là trong hasattr()đó chỉ là một getattr()cuộc gọi được gói trong a try/except. Tuy nhiên, xử lý ngoại lệ chậm hơn so với điều khiển luồng thông thường, do đó, sử dụng nó cho điều gì đó sẽ đúng trong hầu hết thời gian có thể dẫn đến hình phạt hiệu suất.
chào

Có vẻ như nếu bạn muốn có một lớp lót, bạn là SOL
Basic

Ngoài ra pythonic là ý tưởng rằng "tốt hơn là yêu cầu sự tha thứ hơn là sự cho phép", liên quan đến tác động của việc có ngoại lệ rẻ tiền.
heltonbiker

40

Được cập nhật sau khi Alfe chỉ ra rằng bạn không cần phải kiểm tra float riêng vì xử lý phức tạp cả hai:

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True

Trước đây đã nói: Có phải một số trường hợp hiếm hoi bạn cũng có thể cần kiểm tra các số phức (ví dụ 1 + 2i), không thể biểu thị bằng dấu phẩy:

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True

14
Tôi không đồng ý. Điều đó RẤT không thể sử dụng bình thường và tốt hơn là bạn nên xây dựng một cuộc gọi is_complex_number () khi bạn đang sử dụng chúng, thay vì tạo ra một cuộc gọi với hoạt động bổ sung để có cơ hội xử lý sai 0,0001%.
Jiminion

3
Bạn có thể loại bỏ float()hoàn toàn các công cụ và chỉ cần kiểm tra complex()cuộc gọi để thành công. Tất cả mọi thứ được phân tích cú pháp float()có thể được phân tích cú pháp bởi complex().
Alfe

Hàm này sẽ trả về giá trị NaN và Inf của Pandas dưới dạng giá trị số.
fixxxer

complex('(01989)')sẽ trở lại (1989+0j). Nhưng float('(01989)')sẽ thất bại. Vì vậy, tôi nghĩ rằng sử dụng complexkhông phải là ý tưởng tốt.
plhn

26

Để intsử dụng này:

>>> "1221323".isdigit()
True

Nhưng đối với floatchúng tôi cần một số thủ thuật ;-). Mỗi số float có một điểm ...

>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False

Ngoài ra đối với các số âm chỉ cần thêm lstrip():

>>> '-12'.lstrip('-')
'12'

Và bây giờ chúng ta có một cách phổ quát:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False

2
Không xử lý những thứ như 1.234e56và tương tự. Ngoài ra, tôi sẽ quan tâm làm thế nào bạn phát hiện ra đó 99999999999999999999e99999999999999999999không phải là một con số. Cố gắng phân tích nó phát hiện ra một cách nhanh chóng.
Alfe

Điều này chạy nhanh hơn ~ 30% so với giải pháp được chấp nhận trong danh sách chuỗi 50m và nhanh hơn 150% trong danh sách chuỗi 5k. 👏
Zev Averbach

15

Chỉ cần bắt chước C #

Trong C # có hai hàm khác nhau xử lý phân tích các giá trị vô hướng:

  • Float.Pude ()
  • Float.TryPude ()

float.parse ():

def parse(string):
    try:
        return float(string)
    except Exception:
        throw TypeError

Lưu ý: Nếu bạn đang tự hỏi tại sao tôi thay đổi ngoại lệ thành TypeError, thì đây là tài liệu .

float.try_parse ():

def try_parse(string, fail=None):
    try:
        return float(string)
    except Exception:
        return fail;

Lưu ý: Bạn không muốn trả về boolean 'Sai' vì đó vẫn là loại giá trị. Không có gì là tốt hơn bởi vì nó chỉ ra thất bại. Tất nhiên, nếu bạn muốn một cái gì đó khác biệt, bạn có thể thay đổi tham số fail thành bất cứ điều gì bạn muốn.

Để mở rộng float để bao gồm 'parse ()' và 'try_parse ()', bạn sẽ cần phải đánh dấu lớp 'float' để thêm các phương thức này.

Nếu bạn muốn tôn trọng các chức năng có sẵn, mã phải là một cái gì đó như:

def monkey_patch():
    if(!hasattr(float, 'parse')):
        float.parse = parse
    if(!hasattr(float, 'try_parse')):
        float.try_parse = try_parse

SideNote: Cá nhân tôi thích gọi nó là Monkey Punching vì cảm giác như tôi đang lạm dụng ngôn ngữ khi tôi làm điều này nhưng YMMV.

Sử dụng:

float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2

Và Sage Pythonas vĩ đại đã nói với Tòa thánh Sharpisus, "Bất cứ điều gì bạn có thể làm tôi đều có thể làm tốt hơn; tôi có thể làm bất cứ điều gì tốt hơn bạn."


Gần đây tôi đã viết mã trong JS và không thực sự kiểm tra điều này nên có thể có một số lỗi nhỏ. Nếu bạn thấy bất kỳ, hãy thoải mái sửa chữa sai lầm của tôi.
Evan Plaice

Để thêm hỗ trợ cho các số phức, hãy xem câu trả lời của @Matthew Wilcoxson. stackoverflow.com/a/3335060/290340 .
Evan Plaice

1
Sử dụng !thay vì notcó thể là một lỗi nhỏ, nhưng bạn chắc chắn không thể gán các thuộc tính cho floatCPython tích hợp.
BlackJack

15

Đối với các chuỗi không có số, try: except:thực sự chậm hơn các biểu thức thông thường. Đối với chuỗi số hợp lệ, regex chậm hơn. Vì vậy, phương pháp thích hợp phụ thuộc vào đầu vào của bạn.

Nếu bạn thấy rằng bạn đang ở trong một liên kết hiệu suất, bạn có thể sử dụng mô-đun của bên thứ ba mới được gọi là fastnumbers cung cấp một chức năng gọi là isfloat . Tiết lộ đầy đủ, tôi là tác giả. Tôi đã bao gồm kết quả của nó trong thời gian dưới đây.


from __future__ import print_function
import timeit

prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''

prep_try_method = '''\
def is_number_try(val):
    try:
        float(val)
        return True
    except ValueError:
        return False

'''

prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
    return bool(float_match(val))

'''

fn_method = '''\
from fastnumbers import isfloat

'''

print('Try with non-number strings', timeit.timeit('is_number_try(x)',
    prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
    prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
    prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
    prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
    prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
    prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()

Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds

Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds

fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds

Bạn có thể thấy

  • try: except: nhanh cho đầu vào số nhưng rất chậm cho đầu vào không hợp lệ
  • regex rất hiệu quả khi đầu vào không hợp lệ
  • fastnumbers chiến thắng trong cả hai trường hợp

Tôi đứng chính xác: -} nó không giống như đang làm điều này. Có lẽ sử dụng tên như prep_code_basisprep_code_re_methodsẽ ngăn ngừa sai lầm của tôi.
Alfe

Bạn có nhớ giải thích làm thế nào mô-đun của bạn hoạt động, ít nhất là cho isfloatchức năng?
Solomon Ucko

@SolomonUcko Đây là liên kết đến mã nguồn cho phần kiểm tra chuỗi: github.com/SethMMorton/fastnumbers/blob/v1.0.0/src/ . Về cơ bản, nó đi ngang qua từng ký tự trong chuỗi theo thứ tự và xác nhận rằng nó tuân theo một mẫu cho dấu phẩy hợp lệ. Nếu đầu vào đã là một số, nó chỉ sử dụng PyFloat_Check nhanh .
SethMMorton

1
Kiểm tra đối với các lựa chọn thay thế tốt nhất trong chủ đề này, tôi khẳng định giải pháp này là cho đến nay nhanh nhất. Phương pháp nhanh thứ hai str(s).strip('-').replace('.','',1).isdigit()là chậm hơn khoảng 10 lần!
Alexander McFarlane

14

Tôi biết điều này đặc biệt cũ nhưng tôi sẽ thêm một câu trả lời mà tôi tin là bao gồm thông tin còn thiếu trong câu trả lời được bình chọn cao nhất có thể rất có giá trị đối với bất kỳ ai tìm thấy điều này:

Đối với mỗi phương thức sau, hãy kết nối chúng với số đếm nếu bạn cần bất kỳ đầu vào nào được chấp nhận. (Giả sử chúng ta đang sử dụng định nghĩa bằng giọng nói của các số nguyên thay vì 0-255, v.v.)

x.isdigit() hoạt động tốt để kiểm tra nếu x là một số nguyên.

x.replace('-','').isdigit() hoạt động tốt để kiểm tra nếu x là âm. (Kiểm tra - ở vị trí đầu tiên)

x.replace('.','').isdigit() hoạt động tốt để kiểm tra nếu x là số thập phân.

x.replace(':','').isdigit() hoạt động tốt để kiểm tra nếu x là một tỷ lệ.

x.replace('/','',1).isdigit() hoạt động tốt để kiểm tra nếu x là một phân số.


1
Mặc dù đối với phân số, có lẽ bạn cần phải thực hiện x.replace('/','',1).isdigit()hoặc các ngày khác như ngày 4/7/2017 sẽ bị hiểu sai thành số.
Yuxuan Chen

Để biết cách tốt nhất để xâu chuỗi các điều kiện: stackoverflow.com/q 43211771/5922329
Daniel Braun

13

Câu trả lời này cung cấp hướng dẫn từng bước có chức năng với các ví dụ để tìm chuỗi là:

  • Sô nguyên dương
  • Tích cực / tiêu cực - số nguyên / float
  • Làm cách nào để loại bỏ chuỗi "NaN" (không phải số) trong khi kiểm tra số?

Kiểm tra xem chuỗi là dương tính số nguyên

Bạn có thể sử dụng str.isdigit()để kiểm tra xem chuỗi nhất định là dương tính số nguyên.

Kết quả mẫu:

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False

Kiểm tra chuỗi dưới dạng dương / âm - số nguyên / float

str.isdigit()trả về Falsenếu chuỗi là số âm hoặc số float. Ví dụ:

# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False

Nếu bạn cũng muốn kiểm tra các số nguyên âmfloat sau đó bạn có thể viết một hàm tùy chỉnh để kiểm tra nó như sau:

def is_number(n):
    try:
        float(n)   # Type-casting the string to `float`.
                   # If string is not a valid `float`, 
                   # it'll raise `ValueError` exception
    except ValueError:
        return False
    return True

Chạy mẫu:

>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True

>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False

Hủy chuỗi "NaN" (không phải số) trong khi kiểm tra số

Các hàm trên sẽ trả về Truechuỗi "NAN" (Không phải là số) vì đối với Python, đó là float hợp lệ đại diện cho nó không phải là một số. Ví dụ:

>>> is_number('NaN')
True

Để kiểm tra xem số đó có phải là "NaN" hay không, bạn có thể sử dụng math.isnan()như:

>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True

Hoặc nếu bạn không muốn nhập thêm thư viện để kiểm tra điều này, thì bạn có thể chỉ cần kiểm tra nó bằng cách so sánh nó với chính nó bằng cách sử dụng ==. Python trả về Falsekhi nanfloat được so sánh với chính nó. Ví dụ:

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False

Do đó, trên chức năng is_numbercó thể được cập nhật để trở Falsevề"NaN" như sau:

def is_number(n):
    is_number = True
    try:
        num = float(n)
        # check for "nan" floats
        is_number = num == num   # or use `math.isnan(num)`
    except ValueError:
        is_number = False
    return is_number

Chạy mẫu:

>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False

PS: Mỗi thao tác cho mỗi lần kiểm tra tùy thuộc vào loại số đi kèm với chi phí bổ sung. Chọn phiên bản của is_numberchức năng phù hợp với yêu cầu của bạn.


12

Đúc để nổi và bắt ValueError có lẽ là cách nhanh nhất, vì float () đặc biệt chỉ dành cho điều đó. Bất cứ điều gì khác yêu cầu phân tích chuỗi (regex, v.v.) sẽ có thể chậm hơn do thực tế là nó không được điều chỉnh cho thao tác này. 0,02 đô la của tôi.


11
Đô

8
@tzot KHÔNG BAO GIỜ sử dụng số float để thể hiện giá trị tiền tệ.
Lu-ca

6
@Luke: Tôi hoàn toàn đồng ý với bạn, mặc dù tôi chưa bao giờ đề xuất sử dụng phao để thể hiện các giá trị tiền tệ; Tôi chỉ nói rằng các giá trị tiền tệ có thể được biểu diễn dưới dạng float :)
tzot

11

Bạn có thể sử dụng các chuỗi Unicode, họ có một phương pháp để làm những gì bạn muốn:

>>> s = u"345"
>>> s.isnumeric()
True

Hoặc là:

>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True

http://www.tutorialspoint.com/python/opes_isnumeric.htmlm

http://docs.python.org/2/howto/unicode.html


2
đối với ints không âm thì không sao ;-)
andilabs 22/03/2016

1
s.isdecimal()kiểm tra nếu schuỗi là một số nguyên không âm. s.isnumeric()bao gồm các nhân vật int()từ chối.
jfs

9

Tôi muốn xem phương pháp nào là nhanh nhất. Nhìn chung, kết quả tốt nhất và phù hợp nhất đã được đưa ra bởi check_replacechức năng. Các kết quả nhanh nhất được đưa ra bởi check_exceptionhàm, nhưng chỉ khi không có ngoại lệ nào được kích hoạt - có nghĩa là mã của nó là hiệu quả nhất, nhưng chi phí ném ngoại lệ là khá lớn.

Xin lưu ý rằng việc kiểm tra diễn viên thành công là phương pháp duy nhất chính xác, ví dụ: phương pháp này hoạt động với check_exception nhưng hai chức năng kiểm tra khác sẽ trả về Sai cho số float hợp lệ:

huge_number = float('1e+100')

Đây là mã điểm chuẩn:

import time, re, random, string

ITERATIONS = 10000000

class Timer:    
    def __enter__(self):
        self.start = time.clock()
        return self
    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def check_regexp(x):
    return re.compile("^\d*\.?\d*$").match(x) is not None

def check_replace(x):
    return x.replace('.','',1).isdigit()

def check_exception(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

to_check = [check_regexp, check_replace, check_exception]

print('preparing data...')
good_numbers = [
    str(random.random() / random.random()) 
    for x in range(ITERATIONS)]

bad_numbers = ['.' + x for x in good_numbers]

strings = [
    ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
    for x in range(ITERATIONS)]

print('running test...')
for func in to_check:
    with Timer() as t:
        for x in good_numbers:
            res = func(x)
    print('%s with good floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in bad_numbers:
            res = func(x)
    print('%s with bad floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in strings:
            res = func(x)
    print('%s with strings: %s' % (func.__name__, t.interval))

Dưới đây là kết quả với Python 2.7.10 trên MacBook Pro 13 2017:

check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169

Dưới đây là kết quả với Python 3.6.5 trên MacBook Pro 13 2017:

check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002

Dưới đây là kết quả với PyPy 2.7.13 trên MacBook Pro 13 2017:

check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056

10
Bạn cũng nên kiểm tra hiệu suất cho các trường hợp không hợp lệ. Không có ngoại lệ được nêu ra với những con số này, đó chính xác là phần "chậm".
Ugo Méda

1
@ UgoMéda tôi đã lấy lời khuyên của bạn từ năm 2013 và đã làm điều đó :)
Ron Reiter

"Xin lưu ý rằng việc kiểm tra diễn viên thành công là phương pháp duy nhất chính xác" <- điều này thực sự không đúng. Tôi đã chạy thử nghiệm của bạn bằng cách sử dụng biểu thức chính quy trong câu trả lời của tôi ở trên và nó thực sự chạy nhanh hơn biểu thức chính quy. Tôi sẽ thêm kết quả vào câu trả lời của tôi ở trên.
David Ljung Madison Stellar

Ngẫu nhiên, như một điểm thú vị, người tạo số xấu của bạn thực sự có thể tạo ra một số số hợp pháp, mặc dù nó sẽ khá hiếm. :)
David Ljung Madison Stellar

8

Vì vậy, để kết hợp tất cả lại với nhau, kiểm tra Nan, vô cực và số phức (có vẻ như chúng được chỉ định bằng j, không phải i, tức là 1 + 2j), kết quả là:

def is_number(s):
    try:
        n=str(float(s))
        if n == "nan" or n=="inf" or n=="-inf" : return False
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False
    return True

Cho đến nay câu trả lời tốt nhất. Cảm ơn
anish

6

Đầu vào có thể như sau:

a="50" b=50 c=50.1 d="50.1"


1-Đầu vào chung:

Đầu vào của chức năng này có thể là tất cả mọi thứ!

Tìm xem biến đã cho có phải là số không. Chuỗi số bao gồm dấu tùy chọn, bất kỳ số chữ số, phần thập phân tùy chọn và phần số mũ tùy chọn. Do đó + 0123,45e6 là một giá trị số hợp lệ. Không được phép ghi thập lục phân (ví dụ 0xf4c3b00c) và ký hiệu nhị phân (ví dụ 0b10100111001).

is_numeric chức năng

import ast
import numbers              
def is_numeric(obj):
    if isinstance(obj, numbers.Number):
        return True
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            #if used + or - in digit :
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

kiểm tra:

>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True

is_float chức năng

Tìm xem biến đã cho là float. chuỗi float bao gồm dấu tùy chọn, bất kỳ số chữ số nào, ...

import ast

def is_float(obj):
    if isinstance(obj, float):
        return True
    if isinstance(obj, int):
        return False
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        if not isinstance(nodes[-1].n, float):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

kiểm tra:

>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True

ast là gì


2- Nếu bạn tự tin rằng nội dung biến là String :

sử dụng phương thức str.itorigit ()

>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True

3-Đầu vào số:

phát hiện giá trị int:

>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>> 

phát hiện float:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True

" ast" là gì?

4

Tôi đã làm một số bài kiểm tra tốc độ. Hãy nói rằng nếu chuỗi có khả năng là số thì chiến lược thử / ngoại trừ là nhanh nhất có thể. Nếu chuỗi không có khả năng là số bạn quan tâm đến kiểm tra Integer , thì đáng để thực hiện một số kiểm tra (isdigit plus title '-'). Nếu bạn muốn kiểm tra số float, bạn phải sử dụng lệnh thoát / ngoại trừ mã trắng.


4

Tôi cần xác định xem một chuỗi được đúc thành các kiểu cơ bản (float, int, str, bool). Sau khi không tìm thấy bất cứ điều gì trên internet, tôi đã tạo ra điều này:

def str_to_type (s):
    """ Get possible cast type for a string

    Parameters
    ----------
    s : string

    Returns
    -------
    float,int,str,bool : type
        Depending on what it can be cast to

    """    
    try:                
        f = float(s)        
        if "." not in s:
            return int
        return float
    except ValueError:
        value = s.upper()
        if value == "TRUE" or value == "FALSE":
            return bool
        return type(s)

Thí dụ

str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode       

Bạn có thể chụp loại và sử dụng nó

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 

3

RyanN gợi ý

Nếu bạn muốn trả về Sai cho NaN và Inf, hãy đổi dòng thành x = float (s); trả về (x == x) và (x - 1! = x). Điều này sẽ trả về True cho tất cả các số float trừ Inf và NaN

Nhưng điều này không hoàn toàn hiệu quả, vì với số lượng phao đủ lớn, x-1 == xsẽ trả về đúng. Ví dụ,2.0**54 - 1 == 2.0**54


3

Tôi nghĩ rằng giải pháp của bạn là tốt, nhưng có một thực hiện regexp đúng.

Dường như có rất nhiều sự ghét bỏ đối với những câu trả lời này mà tôi nghĩ là không chính đáng, regexps có thể được làm sạch một cách hợp lý và chính xác và nhanh chóng. Nó thực sự phụ thuộc vào những gì bạn đang cố gắng làm. Câu hỏi ban đầu là làm thế nào bạn có thể "kiểm tra xem một chuỗi có thể được biểu diễn dưới dạng số (float)" (theo tiêu đề của bạn). Có lẽ bạn sẽ muốn sử dụng giá trị số / số float sau khi bạn kiểm tra xem nó có hợp lệ không, trong trường hợp đó, lần thử / ngoại trừ của bạn rất có ý nghĩa. Nhưng nếu, vì một số lý do, bạn chỉ muốn xác thực rằng một chuỗi là một sốsau đó một regex cũng hoạt động tốt, nhưng thật khó để sửa. Tôi nghĩ rằng hầu hết các câu trả lời regex cho đến nay, chẳng hạn, không phân tích đúng các chuỗi mà không có phần nguyên (chẳng hạn như ".7"), đây là một câu nổi liên quan đến python. Và đó là một chút khó khăn để kiểm tra trong một regex duy nhất mà phần không cần thiết. Tôi đã bao gồm hai regex để hiển thị điều này.

Nó đặt ra câu hỏi thú vị là "số" là gì. Bạn có bao gồm "inf" có giá trị như một float trong python không? Hoặc bạn có bao gồm các số là "số" nhưng có thể không được biểu thị bằng python (chẳng hạn như số lớn hơn số float tối đa).

Cũng có sự mơ hồ trong cách bạn phân tích số. Ví dụ, còn "- 20" thì sao? Đây có phải là "số" không? Đây có phải là một cách hợp pháp để đại diện cho "20"? Python sẽ cho phép bạn thực hiện "var = --20" và đặt nó thành 20 (mặc dù thực sự điều này là do nó coi nó như một biểu thức), nhưng float ("- 20") không hoạt động.

Dù sao, không có thêm thông tin, đây là một regex mà tôi tin rằng bao gồm tất cả các số nguyên và nổi khi python phân tích chúng .

# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           mantissa (34)
                            #                    exponent (E+56)

# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           OR
                            #             int/mantissa (12.34)
                            #                            exponent (E+56)

def is_float(str):
  return True if FLOAT_REGEXP.match(str) else False

Một số giá trị thử nghiệm ví dụ:

True  <- +42
True  <- +42.42
False <- +42.42.22
True  <- +42.42e22
True  <- +42.42E-22
False <- +42.42e-22.8
True  <- .42
False <- 42nope

Chạy mã điểm chuẩn trong câu trả lời của @ ron-reiter cho thấy rằng regex này thực sự nhanh hơn regex bình thường và xử lý các giá trị xấu nhanh hơn nhiều so với ngoại lệ, điều này có ý nghĩa. Các kết quả:

check_regexp with good floats: 18.001921
check_regexp with bad floats: 17.861423
check_regexp with strings: 17.558862
check_correct_regexp with good floats: 11.04428
check_correct_regexp with bad floats: 8.71211
check_correct_regexp with strings: 8.144161
check_replace with good floats: 6.020597
check_replace with bad floats: 5.343049
check_replace with strings: 5.091642
check_exception with good floats: 5.201605
check_exception with bad floats: 23.921864
check_exception with strings: 23.755481

Hy vọng điều đó đúng - rất thích nghe về bất kỳ ví dụ phản biện nào. :)
David Ljung Madison Stellar

2
import re
def is_number(num):
    pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
    result = pattern.match(num)
    if result:
        return True
    else:
        return False


​>>>: is_number('1')
True

>>>: is_number('111')
True

>>>: is_number('11.1')
True

>>>: is_number('-11.1')
True

>>>: is_number('inf')
False

>>>: is_number('-inf')
False

2
Bạn không xem xét 1e6để đại diện cho một số?
Đánh dấu Dickinson

1

Đây là cách đơn giản của tôi để làm điều đó. Giả sử tôi đang lặp qua một số chuỗi và tôi muốn thêm chúng vào một mảng nếu chúng biến thành số.

try:
    myvar.append( float(string_to_check) )
except:
    continue

Thay thế myvar.apppend bằng bất kỳ thao tác nào bạn muốn thực hiện với chuỗi nếu hóa ra đó là một số. Ý tưởng là thử sử dụng thao tác float () và sử dụng lỗi trả về để xác định xem chuỗi có phải là số hay không.


Bạn nên chuyển phần chắp thêm của hàm đó vào một câu lệnh khác để tránh vô tình kích hoạt ngoại lệ nếu có lỗi xảy ra với mảng.
DarwinSurvivor

1

Tôi cũng đã sử dụng hàm bạn đã đề cập, nhưng ngay sau đó tôi nhận thấy các chuỗi là "Nan", "Inf" và biến thể của nó được coi là số. Vì vậy, tôi đề nghị bạn cải thiện phiên bản chức năng của mình, điều đó sẽ trả về false trên các loại đầu vào đó và sẽ không thất bại với các biến thể "1e3":

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False

1

Mã này xử lý các số mũ, số float và số nguyên, sử dụng regex.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False

1

Chức năng trợ giúp người dùng:

def if_ok(fn, string):
  try:
    return fn(string)
  except Exception as e:
    return None

sau đó

if_ok(int, my_str) or if_ok(float, my_str) or if_ok(complex, my_str)
is_number = lambda s: any([if_ok(fn, s) for fn in (int, float, complex)])

0

Bạn có thể khái quát kỹ thuật ngoại lệ theo cách hữu ích bằng cách trả về nhiều giá trị hữu ích hơn Đúng và Sai. Ví dụ, hàm này đặt dấu ngoặc kép, nhưng chỉ để lại số. Đó chỉ là những gì tôi cần cho một bộ lọc nhanh và bẩn để tạo một số định nghĩa biến cho R.

import sys

def fix_quotes(s):
    try:
        float(s)
        return s
    except ValueError:
        return '"{0}"'.format(s)

for line in sys.stdin:
    input = line.split()
    print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'

0

Tôi đã làm việc với một vấn đề dẫn tôi đến chủ đề này, cụ thể là làm thế nào để chuyển đổi một bộ sưu tập dữ liệu thành chuỗi và số theo cách trực quan nhất. Tôi nhận ra sau khi đọc mã gốc rằng những gì tôi cần là khác nhau theo hai cách:

1 - Tôi muốn một kết quả số nguyên nếu chuỗi đại diện cho một số nguyên

2 - Tôi muốn một số hoặc kết quả chuỗi bám vào cấu trúc dữ liệu

vì vậy tôi đã điều chỉnh mã gốc để tạo ra đạo hàm này:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s

0

Thử cái này.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False

Không thể phản hồi vớiis_number('10')
geotheory

@geotheory, ý bạn là "không phản hồi" nghĩa là gì?
Solomon Ucko

0
def is_float(s):
    if s is None:
        return False

    if len(s) == 0:
        return False

    digits_count = 0
    dots_count = 0
    signs_count = 0

    for c in s:
        if '0' <= c <= '9':
            digits_count += 1
        elif c == '.':
            dots_count += 1
        elif c == '-' or c == '+':
            signs_count += 1
        else:
            return False

    if digits_count == 0:
        return False

    if dots_count > 1:
        return False

    if signs_count > 1:
        return False

    return True
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.