Як визначити, чи рядок починається з числа з Python?


91

У мене є рядок, який починається з числа (від 0 до 9), я знаю, що можу "або" 10 тестових випадків за допомогою startwith (), але, ймовірно, є більш акуратне рішення

так замість того, щоб писати

if (string.startswith('0') || string.startswith('2') ||
    string.startswith('3') || string.startswith('4') ||
    string.startswith('5') || string.startswith('6') ||
    string.startswith('7') || string.startswith('8') ||
    string.startswith('9')):
    #do something

Чи є розумніший / ефективніший спосіб?


Якщо задається питання: "Це занадто повторюється?", Швидше за все - мовою високого рівня - відповідь "Чому, так, це точно". Будь лінивий!

42
Ви пропустили string.startswith('1').
MAK

2
@ Ілюзіоніст Як написано, ваше запитання означає, що ви хочете виявити рядки, які починаються лише з ОДНОЇ цифри. Якщо так, то єдиний правильний відповідь серед наступних з них, не є тими , з використанням s[0]або , s[:1]але рішення Джона Мачин: if s.startswith(tuple('0123456789')). Більше того, це рішення спричиняє помилку, коли трапляється, що s - це послідовність, подібна до кортежу чи списку, у яких випадки дають той самий результат, що і якщо це рядок. - Іншим рішенням є регулярний вираз, шаблон якого '\ d (? = \ D)', але використання регулярного виразу тут зайве.
eyquem

3
Просто бути педантичним: stringце модуль у стандартній бібліотеці і, мабуть, не повинен використовуватися як ім’я змінної. docs.python.org/2/library/string.html
GAK

Відповіді:


170

stringБібліотека Python має isdigit()метод:

string[0].isdigit()

5
string Модуль Python2 не має методів, а isdigitє методом strі unicodeоб'єктів.
Джон Мачин

3
@plaes: -1 через вищезазначений ПЛЮС він виходить з ладу, якщо s == ""
Джон Махін,

3
Подивіться на мою відповідь, яка не порушує порожній рядок:string[:1].isdigit()
PascalVKooten

24
>>> string = '1abc'
>>> string[0].isdigit()
True

Я не хлопець-пітон, тому, можливо, ви можете мені допомогти у цьому: чи буде ця функція бомба на "", де її немає string[0]?
corsiKa

так, це точно буде. ви можете використовувати (рядок або 'x') [0] .isdigit (), щоб виправити це для '' або None
jcomeau_ictx

30
Ви можете спробувати string[:1].isdigit(), що дозволить кинути щасливо мати справу з порожнім рядком.
Саймон Каллан,

2
бо це не моя відповідь; мій все-таки кращий у випадку, коли програміст хоче, щоб виняток був викинутий на порожній рядок.
jcomeau_ictx

1
@jcomeau_ictx точно правильно. ніколи не захищати програму. якщо рядок несподівано порожній, це повинно помилитися і не повинно оброблятися автоматично. Деякі школи думки кажуть, що ви повинні граціозно обробляти та вловлювати винятки, які не є критично важливими, як попередження та підтримувати програму. Я не з таким настроєм для більшості випадків використання. Специфічність функцій та коду, який ви пишете, допомагає зменшити крайні випадки, коли вам доведеться частіше захищати код.
jamescampbell

10

іноді ви можете використовувати регулярний вираз

>>> import re
>>> re.search('^\s*[0-9]',"0abc")
<_sre.SRE_Match object at 0xb7722fa8>

надмірне! Навіщо використовувати re, коли ви можете це зробити в bultins
Якоб Боєр

1
@JakobBowyer Принаймні, про це добре знати! Хоча в цьому випадку так, регулярні вирази НЕ переборюють, якщо деякі вбудовані файли можуть робити те саме.
jeromej

8

Ваш код не працюватиме; вам потрібно orзамість|| .

Спробуйте

'0' <= strg[:1] <= '9'

або

strg[:1] in '0123456789'

або, якщо ви справді божевільні startswith,

strg.startswith(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'))

Я б вас проголосував, якби рішення було лише з startwith (кортежем) . Але рішення з strg[:1]двома незручностями: вони не викликають помилки, якщо s може бути випадковим списком рядків, і вони видають True, якщо рядок починається з НЯКОЛЬКИХ цифр.
eyquem

@eyquem вони видають True, якщо рядок починається з НЯКОЛЬКО цифр. Так? Інші відповіді не перевіряють цього, оскільки не потрібно було перевіряти, чи інші символи не є числовими.
Роб Грант,

Я являюсь божевільним startswithі зробив реалізувати це так в моєму коді. Дякую.
jamescampbell

Ще один старт з можливістю ...startswith(tuple(str(i) for i in range(10)))
Jérôme

4

Цей фрагмент коду:

for s in ("fukushima", "123 is a number", ""):
    print s.ljust(20),  s[0].isdigit() if s else False

роздруковує наступне:

fukushima            False
123 is a number      True
                     False

4
Це негарно. Use s[:1].isdigit()ors and s[0].isdigit()
John Machin

1
@ John Machin Що ви маєте на увазі під словом "потворний"? Не читається? Я не вважаю ваші пропозиції тут вище більш читабельними. s and s[0].isdigit()на мою думку ще менше читається. Особисто мені подобається конструкція ... якщо ... ще ... Беручи до уваги ваше зауваження, я б просто покращив її так:s[0].isdigit() if s!="" else False
eyquem

3

Дивно, що через такий довгий час все ще не вистачає найкращої відповіді.

Негативною стороною інших відповідей є використання [0] першого символу, але, як зазначалося, це позначається на порожньому рядку.

Використовуючи наведене нижче, ми обходимо цю проблему і, на мій погляд, надаємо найкрасивіший і читабельніший синтаксис з усіх можливих варіантів. Він також не імпортує / не турбує регулярний вираз):

>>> string = '1abc'
>>> string[:1].isdigit()
True

>>> string = ''
>>> string[:1].isdigit()
False


1

Ось мої "відповіді" (намагаючись бути унікальним тут, я насправді не рекомендую ні для цього конкретного випадку :-)

Використовуючи ord () таспеціальна a <= b <= cформа:

//starts_with_digit = ord('0') <= ord(mystring[0]) <= ord('9')
//I was thinking too much in C. Strings are perfectly comparable.
starts_with_digit = '0' <= mystring[0] <= '9'

(Це a <= b <= c, як a < b < c, є спеціальною конструкцією Python, і вона якось акуратна: порівняти 1 < 2 < 3(true) та 1 < 3 < 2(false) та (1 < 3) < 2(true). Це не так, як це працює у більшості інших мов.)

Використання регулярного виразу :

import re
//starts_with_digit = re.match(r"^\d", mystring) is not None
//re.match is already anchored
starts_with_digit = re.match(r"\d", mystring) is not None

1
(1) Втратити ord()(2) Втратити ^в регулярному виразі.
John Machin,

0

Ви можете використовувати регулярні вирази .

Ви можете виявити цифри, використовуючи:

if(re.search([0-9], yourstring[:1])):
#do something

Параметр [0-9] відповідає будь-якій цифрі, а ваш рядок [: 1] - першому символу вашого рядка



-5

Спробуйте це:

if string[0] in range(10):

Це взагалі не працює. range(10)створює список цілих чисел, тоді string[0]як це рядок довжиною 1.
Петрі Лехтінен

1
Це не працює; типи не збігаються. Але: if string[0] in map(str,range(10))працює
phynfo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.