Як визначити, чи рядок починається з числа з 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.