Πώς μπορώ να ελέγξω αν ένα string είναι ένας αριθμός (float);

ψήφοι
1k

Ποιος είναι ο καλύτερος δυνατός τρόπος για να ελέγξετε αν μια σειρά μπορεί να παρασταθεί ως αριθμός στην Python;

Η λειτουργία που σήμερα έχουν αυτή τη στιγμή είναι:

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

Η οποία, όχι μόνο είναι άσχημο και αργή, φαίνεται ογκώδη. Ωστόσο, δεν έχω βρει μια καλύτερη μέθοδο, διότι καλεί floatστην κύρια λειτουργία είναι ακόμη χειρότερη.

Δημοσιεύθηκε 09/12/2008 στις 21:03
πηγή χρήστη
Σε άλλες γλώσσες...                            


34 απαντήσεις

ψήφοι
1k

Σε περίπτωση που ψάχνετε για την ανάλυση (θετική, χωρίς υπογραφή) ακέραιοι αντί για πλωτήρες, μπορείτε να χρησιμοποιήσετε τη isdigit()λειτουργία για αντικείμενα εγχόρδων.

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

Μέθοδοι String - isdigit()

Υπάρχει επίσης κάτι για Unicode χορδές, το οποίο δεν είμαι πολύ εξοικειωμένος με Unicode - Είναι δεκαδικά / δεκαδικά

Απαντήθηκε 09/12/2008 στις 21:15
πηγή χρήστη

ψήφοι
556

Η οποία, όχι μόνο είναι άσχημο και αργή

Θα αμφισβητήσει τα δύο.

Μια τυπική έκφραση ή άλλη ανάλυση της συμβολοσειράς θα ήταν πιο άσχημο και πιο αργή.

Δεν είμαι σίγουρος ότι κάτι πολύ θα μπορούσε να είναι πιο γρήγορα από τα παραπάνω. Καλεί τη λειτουργία και επιστρέφει. Προσπαθήστε / αλιευμάτων δεν εισάγει πολύ γενικά, γιατί η πιο συνηθισμένη εξαίρεση πιάνεται χωρίς εκτεταμένη έρευνα των πλαισίων στοίβας.

Το θέμα είναι ότι κάθε αριθμητική λειτουργία μετατροπής έχει δύο είδη αποτελεσμάτων

  • Ένας αριθμός, αν ο αριθμός είναι έγκυρη
  • Ένας κωδικός κατάστασης (π.χ., μέσω errno) ή εξαίρεση για να δείξει ότι δεν είναι έγκυρο αριθμό θα μπορούσε να αναλυθεί.

C (ως παράδειγμα) αμυχές γύρω από αυτό ένας αριθμός τρόπων. Python καθορίζει σαφώς και ρητά.

Νομίζω κωδικό σας για να γίνει αυτό είναι τέλειο.

Απαντήθηκε 09/12/2008 στις 21:30
πηγή χρήστη

ψήφοι
62

Υπάρχει μία εξαίρεση που μπορεί να θέλετε να λάβουν υπόψη: το string «NaN»

Αν θέλετε is_number να επιστρέψει FALSE για «NaN» αυτόν τον κώδικα δεν θα λειτουργήσει ως Python μετατρέπει την εκπροσώπηση της έναν αριθμό που δεν είναι ένας αριθμός (συζήτηση για τα ζητήματα της ταυτότητας):

>>> float('NaN')
nan

Σε αντίθετη περίπτωση, θα πρέπει πραγματικά να σας ευχαριστήσω για το κομμάτι του κώδικα που τώρα χρησιμοποιούν εκτενώς. :)

ΣΟΛ.

Απαντήθηκε 01/09/2010 στις 15:06
πηγή χρήστη

ψήφοι
56

TL? DR Η καλύτερη λύση είναιs.replace('.','',1).isdigit()

Έκανα κάποια σημεία αναφοράς τη σύγκριση των διαφορετικών προσεγγίσεων

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

Αν η σειρά δεν είναι ένας αριθμός, η εξαίρεση μπλοκ είναι πολύ αργή. Αλλά το πιο σημαντικό, η προσπάθεια, εκτός της μεθόδου είναι η μόνη προσέγγιση που χειρίζεται σωστά επιστημονική σημειογραφία.

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

Float ένδειξη»0.1234" δεν υποστηρίζεται από:
- 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__)

Η επιστημονική σημειογραφία "1.000000e + 50" δεν υποστηρίζεται από:
- is_number_regex
- is_number_repl_isdigit
επιστημονική σημειογραφία "1e50" δεν υποστηρίζεται από:
- is_number_regex
- is_number_repl_isdigit

EDIT: Τα αποτελέσματα αναφοράς

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

όπου δοκιμάστηκαν οι ακόλουθες λειτουργίες

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

εισάγετε περιγραφή της εικόνας εδώ

Απαντήθηκε 13/05/2014 στις 20:28
πηγή χρήστη

ψήφοι
51

τι λες για αυτό:

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

η οποία θα επιστρέψει ισχύει μόνο αν υπάρχει ή όχι ». στη σειρά των ψηφίων.

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

θα επιστρέψει false

edit: μόλις είδα ένα άλλο σχόλιο ... προσθήκη ενός .replace(badstuff,'',maxnum_badstuff)για άλλες περιπτώσεις μπορεί να γίνει. αν περνάτε το αλάτι και όχι αυθαίρετη καρυκεύματα (ref: xkcd # 974 ) θα κάνει μια χαρά: P

Απαντήθηκε 25/05/2012 στις 23:22
πηγή χρήστη

ψήφοι
37

Ενημερώθηκε μετά Alfe επεσήμανε ότι δεν πρέπει να ελέγξετε για πλωτήρα ξεχωριστά ως συγκρότημα χειρίζεται δύο:

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

    return True

Προηγουμένως είπε: Είναι μερικές σπάνιες περιπτώσεις μπορεί επίσης να χρειαστεί να ελέγξετε για μιγαδικών αριθμών (π.χ. 1 + 2i), η οποία δεν μπορεί να εκπροσωπείται από έναν πλωτήρα:

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
Απαντήθηκε 26/07/2010 στις 14:10
πηγή χρήστη

ψήφοι
37

Η οποία, όχι μόνο είναι άσχημο και αργή, φαίνεται ογκώδη.

Μπορεί να χρειαστεί κάποιος να συνηθίσει, αλλά αυτή είναι η pythonic τρόπος για να γίνει αυτό. Όπως έχει ήδη επισημανθεί, οι εναλλακτικές λύσεις είναι χειρότερες. Αλλά υπάρχει ένα άλλο πλεονέκτημα του να κάνει τα πράγματα με αυτόν τον τρόπο: πολυμορφισμό.

Η κεντρική ιδέα πίσω από πάπια πληκτρολογώντας είναι ότι «αν περπατά και να μιλά σαν πάπια, τότε είναι μια πάπια.» Τι και αν αποφασίσετε ότι θα πρέπει να υποτάξη κλωστή, έτσι ώστε να μπορείτε να αλλάξετε τον τρόπο να προσδιορίσετε αν κάτι μπορεί να μετατραπεί σε ένα πλωτήρα; Ή ό, τι και αν αποφασίσετε να δοκιμάσετε κάποιο άλλο αντικείμενο εντελώς; Μπορείτε να κάνετε αυτά τα πράγματα χωρίς να χρειάζεται να αλλάξετε τον παραπάνω κώδικα.

Άλλες γλώσσες επίλυση αυτών των προβλημάτων με τη χρήση διεπαφών. Θα σώσει την ανάλυση των οποίων η λύση είναι καλύτερη για ένα άλλο νήμα. Το θέμα, όμως, είναι ότι η python είναι αναμφισβήτητα από την πλευρά πάπια πληκτρολόγηση της εξίσωσης, και πρόκειται πιθανώς να πρέπει να συνηθίσουν συντακτικής έτσι αν σκοπεύετε να κάνετε πολλά προγραμματισμού Python (αλλά αυτό δεν σημαίνει ότι θα πρέπει να αρέσει φυσικά).

Ένα άλλο πράγμα που μπορεί να θέλετε να λάβετε υπόψη: Python είναι αρκετά γρήγορος σε ρίψη και την αλίευση εξαιρέσεις σε σύγκριση με πολλές άλλες γλώσσες (30x γρηγορότερα από ό, τι .Net, για παράδειγμα). Heck, η ίδια η γλώσσα ρίχνει ακόμη και εξαιρέσεις για να επικοινωνούν μη εξαιρετικές, κανονικές συνθήκες πρόγραμμα (κάθε φορά που χρησιμοποιείτε ένα για το βρόχο). Έτσι, δεν θα ανησυχείτε πάρα πολύ για τα θέματα απόδοση αυτού του κώδικα μέχρι να παρατηρήσετε ένα σημαντικό πρόβλημα.

Απαντήθηκε 11/12/2008 στις 05:56
πηγή χρήστη

ψήφοι
17

Για intτη χρήση αυτή:

>>> "1221323".isdigit()
True

Αλλά για floatχρειαζόμαστε μερικά κόλπα ;-). Κάθε αριθμός float έχει ένα σημείο ...

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

Επίσης, για τους αρνητικούς αριθμούς απλά προσθέστε lstrip():

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

Και τώρα έχουμε ένα καθολικό τρόπο:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False
Απαντήθηκε 08/09/2015 στις 08:42
πηγή χρήστη

ψήφοι
14

Για χορδές της μη αριθμών, try: except:είναι στην πραγματικότητα πιο αργή από ό, τι οι κανονικές εκφράσεις. Για χορδές των έγκυρων αριθμών, regex είναι πιο αργή. Έτσι, η κατάλληλη μέθοδος εξαρτάται από τη συμβολή σας.

Αν διαπιστώσετε ότι είστε σε δύσκολη θέση την απόδοση, μπορείτε να χρησιμοποιήσετε ένα νέο module τρίτων κατασκευαστών που ονομάζεται fastnumbers που παρέχει μια λειτουργία που ονομάζεται isfloat . Πλήρης αποκάλυψη, είμαι ο συγγραφέας. Έχω περιλαμβάνονται τα αποτελέσματα της στα παρακάτω χρόνους.


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

Οπως βλέπεις

  • try: except: Ήταν γρήγορα για αριθμητική είσοδο, αλλά πολύ αργή για μη έγκυρη είσοδο
  • regex είναι πολύ αποτελεσματική όταν η είσοδος δεν είναι έγκυρη
  • fastnumbers κερδίζει και στις δύο περιπτώσεις
Απαντήθηκε 14/08/2014 στις 04:34
πηγή χρήστη

ψήφοι
14

Απλά Μιμούνται C #

Στην C #, υπάρχουν δύο διαφορετικές λειτουργίες που χειρίζονται την ανάλυση των βαθμωτών τιμών:

  • Float.Parse ()
  • Float.TryParse ()

float.parse ():

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

Σημείωση: Αν αναρωτιέστε γιατί άλλαξα την εξαίρεση σε TypeError, εδώ είναι η τεκμηρίωση .

float.try_parse ():

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

Σημείωση: Δεν θέλετε να επιστρέψετε το boolean «Λάθος», γιατί αυτό είναι ακόμα ένα είδος τιμής. Καμία δεν είναι καλύτερη, γιατί δείχνει την αποτυχία. Φυσικά, αν θέλετε κάτι διαφορετικό, μπορείτε να αλλάξετε την παράμετρο δεν ό, τι θέλετε.

Για την επέκταση πλωτήρα να συμπεριλάβει το «ανάλυσης ()» και «try_parse ()» θα πρέπει να monkeypatch την κατηγορία «επιπλέουν» για να προσθέσει αυτές τις μεθόδους.

Αν θέλετε σεβαστεί τις προϋπάρχουσες λειτουργίες ο κώδικας θα πρέπει να είναι κάτι σαν:

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

Υποσημείωση: Εγώ προσωπικά προτιμώ να την αποκαλούμε Διάτρηση μαϊμού γιατί αισθάνεται σαν να είμαι κατάχρηση της γλώσσας όταν το κάνω αυτό, αλλά YMMV.

Χρήση:

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

Και το μεγάλο Sage Πύθωνα, δήλωσε στην Αγία Έδρα Sharpisus, «Ό, τι μπορείτε να κάνετε μπορώ να κάνω καλύτερα? Μπορώ να κάνω κάτι καλύτερο από σένα.»

Απαντήθηκε 18/02/2012 στις 02:35
πηγή χρήστη

ψήφοι
13

Ξέρω ότι αυτό είναι ιδιαίτερα παλιό, αλλά θα ήθελα να προσθέσω μια απάντηση πιστεύω ότι καλύπτει τις πληροφορίες που λείπουν από το υψηλότερο ψηφιστεί απάντηση που θα μπορούσε να είναι πολύ πολύτιμη για όποιον βρει αυτό:

Για κάθε μία από τις ακόλουθες μεθόδους τους συνδέουν με μια καταμέτρηση, αν χρειάζεστε οποιαδήποτε είσοδο για να γίνει αποδεκτή. (Υποθέτοντας ότι χρησιμοποιούμε φωνητικές τους ορισμούς των ακεραίων και όχι 0-255, κλπ)

x.isdigit() λειτουργεί καλά για τον έλεγχο αν το x είναι ακέραιος.

x.replace('-','').isdigit() λειτουργεί καλά για τον έλεγχο αν το x είναι αρνητική (Check - στην πρώτη θέση).

x.replace('.','').isdigit() λειτουργεί καλά για τον έλεγχο αν το x είναι ένας δεκαδικός.

x.replace(':','').isdigit() λειτουργεί καλά για τον έλεγχο, εάν το Χ είναι μια αναλογία.

x.replace('/','',1).isdigit() λειτουργεί καλά για τον έλεγχο αν το x είναι ένα κλάσμα.

Απαντήθηκε 05/01/2016 στις 15:21
πηγή χρήστη

ψήφοι
10

Μπορείτε να χρησιμοποιήσετε Unicode χορδές, έχουν μια μέθοδο για να κάνει ακριβώς ό, τι θέλετε:

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

Ή:

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

http://www.tutorialspoint.com/python/string_isnumeric.htm

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

Απαντήθηκε 04/03/2013 στις 17:12
πηγή χρήστη

ψήφοι
9

Casting να επιπλέουν και να πιάσει ValueError είναι ίσως ο πιο γρήγορος τρόπος, δεδομένου ότι πλωτήρα () είναι ειδικά σήμαινε για ακριβώς αυτό. Οτιδήποτε άλλο που απαιτεί string parsing (regex, κλπ) πιθανότατα θα είναι πιο αργή, λόγω του γεγονότος ότι δεν είναι συντονισμένοι για αυτήν τη λειτουργία. My $ 0,02.

Απαντήθηκε 09/12/2008 στις 21:31
πηγή χρήστη

ψήφοι
8

Ας πούμε ότι έχετε ψηφία στα κορδόνι. str = «100949» και θα θέλατε να ελέγξετε αν έχει μόνο αριθμούς

if str.isdigit():
returns TRUE or FALSE 

isdigit έγγραφα

Αλλιώς η μέθοδος σας λειτουργεί μεγάλο για να βρούμε την εμφάνιση ενός ψηφίου σε μια σειρά.

Απαντήθηκε 13/10/2014 στις 10:17
πηγή χρήστη

ψήφοι
7

Ήθελα να δω ποια μέθοδος είναι ταχύτερη. Συνολικά τα καλύτερα και πιο σταθερά αποτελέσματα δόθηκαν από τη check_replaceλειτουργία. Τα γρηγορότερα αποτελέσματα δόθηκαν από την check_exceptionλειτουργία, αλλά μόνο αν δεν υπήρχε καμία εξαίρεση απολυθούν - που σημαίνει τον κωδικό του είναι η πιο αποτελεσματική, αλλά η επιβάρυνση του ρίχνουν μια εξαίρεση είναι αρκετά μεγάλο.

Παρακαλείστε να σημειώσετε ότι ο έλεγχος για ένα επιτυχημένο καστ είναι η μόνη μέθοδος η οποία είναι ακριβή, για παράδειγμα, αυτό λειτουργεί με check_exception, αλλά οι άλλες δύο λειτουργίες ελέγχου θα επιστρέψει False για μια έγκυρη float:

huge_number = float('1e+100')

Εδώ είναι ο κώδικας αναφοράς:

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

Εδώ είναι τα αποτελέσματα με Python 2.7.10 σε 2017 MacBook Pro 13:

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

Εδώ είναι τα αποτελέσματα με Python 3.6.5 σε 2017 MacBook Pro 13:

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

Εδώ είναι τα αποτελέσματα με PyPy 07/02/13 σε 2017 MacBook Pro 13:

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
Απαντήθηκε 16/01/2013 στις 07:09
πηγή χρήστη

ψήφοι
6

Έτσι για να πούμε όλοι μαζί, ο έλεγχος για Nan, το άπειρο και μιγαδικών αριθμών (φαίνεται ότι καθορίζονται με ι, δεν μπορώ, δηλαδή 1 + 2ι) έχει ως αποτέλεσμα:

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
Απαντήθηκε 23/03/2012 στις 17:10
πηγή χρήστη

ψήφοι
5

Ο κωδικός σας φαίνεται μια χαρά για μένα.

Ίσως νομίζετε ότι ο κωδικός είναι «ογκώδη» λόγω της χρήσης εξαιρέσεις; Σημειώστε ότι η Python προγραμματιστές τείνουν να χρησιμοποιούν εξαιρέσεις γενναιόδωρα όταν βελτιώνει την αναγνωσιμότητα κωδικό, χάρη στο χαμηλό ποινή επιδόσεων του.

Απαντήθηκε 11/12/2008 στις 05:03
πηγή χρήστη

ψήφοι
4

Αυτή η απάντηση παρέχει βήμα προς βήμα οδηγό που έχει η λειτουργία με παραδείγματα για να βρείτε το string είναι:

  • Θετικός ακέραιος
  • Θετική / αρνητική - ακέραιος / float
  • Πώς να απορρίψει «NaN» (όχι τον αριθμό) χορδές κατά τον έλεγχο για τον αριθμό;

Ελέγξτε αν string είναι θετικός ακέραιος

Μπορείτε να χρησιμοποιήσετε str.isdigit()για να ελέγξει κατά πόσον δεδομένη συμβολοσειρά είναι θετικός ακέραιος.

Δείγμα Αποτελέσματα:

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

Ελέγξτε για εγχόρδων ως θετική / αρνητική - ακέραιος / float

str.isdigit()επιστρέφει Falseεάν η συμβολοσειρά είναι ένας αρνητικός αριθμός ή ένας αριθμός πλωτήρα. Για παράδειγμα:

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

Αν θέλετε να ελέγξετε και για τις αρνητικές ακέραιοι καιfloat , στη συνέχεια, μπορείτε να γράψετε μια προσαρμοσμένη συνάρτηση για να ελέγξετε για αυτό, όπως:

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

Δείγμα Run:

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

Πετάξτε «NaN» (όχι τον αριθμό) χορδές κατά τον έλεγχο για τον αριθμό

Οι παραπάνω λειτουργίες θα επιστρέψει Trueγια την «NAN» (Δεν είναι ένας αριθμός) χορδή επειδή για Python είναι έγκυρη float που αντιπροσωπεύει δεν είναι ένας αριθμός. Για παράδειγμα:

>>> is_number('NaN')
True

Για να ελέγξετε αν ο αριθμός είναι «NaN», μπορείτε να χρησιμοποιήσετε math.isnan()ως εξής:

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

>>> math.isnan(nan_num)
True

Ή αν δεν θέλετε να εισαγάγετε πρόσθετες βιβλιοθήκη για να το ελέγξετε, τότε μπορείτε απλά να το ελέγξετε μέσω συγκρίνοντάς το με τον εαυτό του με τη χρήση ==. Python επιστρέφει Falseόταν nanπλωτήρας συγκρίνεται με τον εαυτό της. Για παράδειγμα:

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

Ως εκ τούτου, ανωτέρω λειτουργία is_numberμπορεί να ενημερωθεί για να επιστρέψει Falseγια"NaN" ως:

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

Δείγμα Run:

>>> 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: Κάθε λειτουργία για κάθε έλεγχο ανάλογα με τον τύπο του αριθμού έρχεται με πρόσθετη επιβάρυνση. Επιλέξτε την έκδοση του is_numberλειτουργία που ταιριάζει τις ανάγκες σας.

Απαντήθηκε 11/02/2018 στις 08:34
πηγή χρήστη

ψήφοι
4

Έπρεπε να καθοριστεί εάν μια σειρά ρίχνει σε βασικά είδη (float, int, str, bool). Μετά δεν βρίσκει τίποτα στο διαδίκτυο που δημιουργήθηκε το εξής:

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)

Παράδειγμα

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       

Μπορείτε να συλλάβει τον τύπο και να το χρησιμοποιήσετε

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 
Απαντήθηκε 03/07/2014 στις 18:12
πηγή χρήστη

ψήφοι
4

Έκανα κάποια ταχύτητα δοκιμής. Ας πούμε ότι αν η σειρά είναι πιθανό να είναι ένας αριθμός ο δοκιμή / εκτός στρατηγική είναι ο πιο γρήγορος possible.If η σειρά είναι δεν είναι πιθανό να είναι μια σειρά και σας ενδιαφέρει Ακέραιος έλεγχο, αξίζει να κάνετε κάποια τεστ (isdigit συν τίτλο '-'). Αν σας ενδιαφέρει να ελέγξετε τον αριθμό float, θα πρέπει να χρησιμοποιήσετε τη δοκιμή / εκτός από τον κωδικό whitout διαφυγής.

Απαντήθηκε 12/10/2010 στις 08:43
πηγή χρήστη

ψήφοι
3

Η είσοδος μπορεί να είναι ως εξής:

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


1 Γενική είσοδος:

Η είσοδος αυτής της λειτουργίας μπορεί να είναι τα πάντα!

Βρίσκει κατά πόσον η δεδομένη μεταβλητή είναι αριθμητικό. Αριθμητική χορδές αποτελούνται από προαιρετική ένδειξη, οποιοδήποτε αριθμό των ψηφίων, προαιρετικά δεκαδικό μέρος και προαιρετικό εκθετικό μέρος. Έτσι + 0123.45e6 είναι μια έγκυρη αριθμητική τιμή. Δεκαεξαδική (π.χ. 0xf4c3b00c) και δυαδικά (π.χ. 0b10100111001) συμβολισμός δεν επιτρέπεται.

is_numeric λειτουργία

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

δοκιμή:

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

is_float λειτουργία

Βρίσκει κατά πόσον η δεδομένη μεταβλητή είναι πλωτήρα. επιπλέουν χορδές αποτελούνται από προαιρετική ένδειξη, οποιοσδήποτε αριθμός ψηφίων, ...

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

δοκιμή:

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

τι είναι ast ;


2 Αν είστε βέβαιοι ότι η μεταβλητή περιεχόμενο είναι String :

χρήση str.isdigit () μέθοδος

>>> 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-Αριθμητική εισόδου:

ανίχνευση int τιμή:

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

ανιχνεύουν πλωτήρα:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True
Απαντήθηκε 06/10/2018 στις 07:23
πηγή χρήστη

ψήφοι
3

Ryann προτείνει

Αν θέλετε να επιστρέψετε False για NaN και Inf, αλλαγή γραμμής στο x = πλωτήρα (s)? επιστροφή (x == x) και (x! - 1 = x). Αυτό θα πρέπει να επιστρέψει True για όλα τα άρματα, εκτός Inf και NaN

Αλλά αυτό δεν εργάζονται αρκετά, γιατί για αρκετά μεγάλο άρματα, x-1 == xεπιστρέφει true. Για παράδειγμα,2.0**54 - 1 == 2.0**54

Απαντήθηκε 29/07/2013 στις 15:08
πηγή χρήστη

ψήφοι
1

Θα χρησιμοποιηθεί επίσης τη λειτουργία που αναφέρατε, αλλά σύντομα θα παρατηρήσετε ότι χορδές ως «Nan», «Inf» και είναι παραλλαγή θεωρούνται αριθμό. Γι 'αυτό προτείνουμε να βελτιωμένη έκδοση της λειτουργίας σας, που θα επιστρέψει false για εκείνους τους τύπους των εισροών και δεν θα αποτύχει «1Ε3» παραλλαγές:

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False
Απαντήθηκε 15/10/2016 στις 21:11
πηγή χρήστη

ψήφοι
1

Μπορείτε να χρησιμοποιήσετε το regex.

number = raw_input("Enter a number: ")
if re.match(r'^\d+$', number):
    print "It's integer"
    print int(number)
elif re.match(r'^\d+\.\d+$', number):
    print "It's float"
    print float(number)
else:
    print("Please enter a number")
Απαντήθηκε 23/08/2015 στις 13:22
πηγή χρήστη

ψήφοι
1

Δοκιμάστε αυτό.

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False
Απαντήθηκε 30/05/2015 στις 17:12
πηγή χρήστη

ψήφοι
1

Δούλευα σε ένα πρόβλημα που με οδήγησε σε αυτό το νήμα, δηλαδή πώς να μετατρέψετε μια συλλογή των δεδομένων για έγχορδα και αριθμούς με τον πιο έξυπνο τρόπο. Συνειδητοποίησα μετά την ανάγνωση του αρχικού κώδικα ότι αυτό που χρειαζόταν ήταν διαφορετική με δύο τρόπους:

1 - Ήθελα έναν ακέραιο αποτέλεσμα αν η συμβολοσειρά εκπροσωπείται έναν ακέραιο

2 - Ήθελα ένα αριθμό ή ένα αποτέλεσμα συμβολοσειρά να κολλήσει σε μια δομή δεδομένων

γι 'αυτό προσαρμόζεται του αρχικού κώδικα για την παραγωγή αυτής παράγωγο:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s
Απαντήθηκε 09/11/2014 στις 14:06
πηγή χρήστη

ψήφοι
1

Εδώ είναι απλά ο τρόπος μου για να γίνει αυτό. Ας πούμε ότι είμαι looping μέσα από κάποιες χορδές και θέλω να τα προσθέσετε σε μια σειρά, εάν αποδειχθεί ότι είναι αριθμοί.

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

Αντικαταστήστε το myvar.apppend με ό, τι τη λειτουργία που θέλετε να κάνετε με το κορδόνι και αν αποδεικνύεται ότι είναι ένας αριθμός. Η ιδέα είναι να προσπαθήσετε να χρησιμοποιήσετε μια λειτουργία float () και να χρησιμοποιήσετε το επέστρεψε σφάλμα να καθοριστεί εάν ή όχι η σειρά είναι ένας αριθμός.

Απαντήθηκε 16/07/2009 στις 18:45
πηγή χρήστη

ψήφοι
1

Αν θέλετε να μάθετε αν το σύνολο της συμβολοσειράς μπορεί να αναπαρασταθεί ως ένας αριθμός που θα θελήσετε να χρησιμοποιήσετε μια κανονική έκφραση (ή ίσως και να μετατρέψει τον πλωτήρα πίσω σε μια σειρά και να το συγκρίνετε με το κορδόνι πηγή, αλλά υποθέτω ότι δεν είναι πολύ γρήγορη ).

Απαντήθηκε 10/12/2008 στις 10:15
πηγή χρήστη

ψήφοι
0

Αυτός ο κωδικός χειρίζεται τις εκθέτες, άρματα και ακέραιοι, wihtout χρησιμοποιώντας regex.

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False
Απαντήθηκε 16/12/2018 στις 07:12
πηγή χρήστη

ψήφοι
0
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
Απαντήθηκε 02/08/2018 στις 11:06
πηγή χρήστη

ψήφοι
0

χρησιμοποιήσετε το παρακάτω χειρίζεται όλες τις υποθέσεις: -

import re
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3') 
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3sd')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3')
Απαντήθηκε 24/02/2017 στις 11:11
πηγή χρήστη

ψήφοι
0

Για να ελέγξετε αν η τιμή εισόδου είναι ένα float, μπορείτε να συγκρίνετε τον τύπο της εισόδου σε έναfloat

def isFloat(s):
    realFloat = 0.1

    if type(s) == type(realFloat):
        return True
    else:
        return False

Επιστροφές:

False     # s = 5
True      # s = 1.2345

Το αρχικό post θα επιστρέψει στην πραγματικότητα Trueγια s = 5δεδομένου ότι είναι μια σειρά (ακέραιος αριθμός) και μπορείτε να ρίχνει μια intμε μια floatχωρίς ένα ValueError. Αν προσπαθείτε να επαληθεύσετε ότι πρόκειται για μια πραγματική floatκαι όχι απλώς έναν αριθμό, θα πρέπει να λογοδοτήσουν για αυτή την περίπτωση.

Απαντήθηκε 16/09/2016 στις 05:00
πηγή χρήστη

ψήφοι
0

Μπορείτε να γενικεύσει την τεχνική εξαίρεση ένα χρήσιμο τρόπο, επιστρέφοντας πιο χρήσιμο τιμές από True και False. Για παράδειγμα, η λειτουργία αυτή βάζει εισαγωγικά γύρω από χορδές, αλλά αφήνει τους αριθμούς και μόνο. Ποια είναι ακριβώς αυτό που χρειαζόμουν για ένα γρήγορο και βρώμικο φίλτρο για να κάνει κάποιες μεταβλητές ορισμούς για 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:]), ')'
Απαντήθηκε 24/05/2013 στις 22:36
πηγή χρήστη

ψήφοι
-1

Έχω ένα παρόμοιο πρόβλημα. Αντί να ορίζει μια συνάρτηση ISNUMBER, θέλω να μετατρέψει έναν κατάλογο των χορδών να επιπλέει, γεγονός που από πλευράς υψηλού επιπέδου θα είναι:

[ float(s) for s in list if isFloat(s)]

Είναι δεδομένο ότι δεν μπορεί να διαχωρίσει πραγματικά το φλοτέρ (ες) από τις λειτουργίες isFloat (ες): αυτά τα δύο αποτελέσματα θα πρέπει να επιστραφεί από την ίδια λειτουργία. Επίσης, εάν πλωτήρα (s) αποτυγχάνει, η όλη διαδικασία αποτύχει, αντί απλώς αγνοώντας το ελαττωματικό στοιχείο. Πλέον, «0» είναι ένα έγκυρο αριθμό και θα πρέπει να συμπεριληφθούν στον κατάλογο. Όταν το φιλτράρισμα κακά στοιχεία, είναι βέβαιο ότι δεν θα αποκλείσει 0.

Ως εκ τούτου, η παραπάνω κατανόηση πρέπει να τροποποιηθεί με κάποιο τρόπο να:

  • αν κάθε στοιχείο της λίστας δεν μπορούν να μετατραπούν, το αγνοήσετε και να μην ρίξει μια εξαίρεση
  • αποφεύγουν να καλέσουν πλωτήρα (-α) πάνω από μία φορά για κάθε στοιχείο (ένα για τη μετατροπή, η άλλη για τη δοκιμή)
  • αν η μετατροπή τιμή είναι 0, θα πρέπει να εξακολουθεί να είναι παρούσα στον τελικό κατάλογο

Προτείνω μια λύση εμπνευσμένο στα nullable αριθμητικών τύπων C #. Αυτοί οι τύποι είναι εσωτερικά αντιπροσωπεύεται από ένα struct που έχει την αριθμητική αξία και προσθέτει μια boolean που δείχνει αν η τιμή είναι έγκυρη:

def tryParseFloat(s):
    try:
        return(float(s), True)
    except:
        return(None, False)

tupleList = [tryParseFloat(x) for x in list]
floats = [v for v,b in tupleList if b]
Απαντήθηκε 18/03/2018 στις 00:18
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more