จะทราบได้อย่างไรว่าสตริงเริ่มต้นด้วยตัวเลขด้วย Python?


95

ฉันมีสตริงที่ขึ้นต้นด้วยตัวเลข (ตั้งแต่ 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
@Illusionist ตามที่เขียนไว้คำถามของคุณหมายความว่าคุณต้องการตรวจจับสตริงที่ขึ้นต้นด้วยตัวเลขเพียงหลักเดียว ถ้าเป็นเช่นนั้นคำตอบเดียวที่เหมาะสมในหมู่คนดังต่อไปนี้ไม่ได้เป็นคนที่ใช้s[0]หรือแต่การแก้ปัญหาของจอห์นเมชินไปนี้:s[:1] if s.startswith(tuple('0123456789'))ยิ่งไปกว่านั้นการแก้ปัญหานี้ทำให้เกิดข้อผิดพลาดเมื่อเกิดขึ้นว่าsเป็นลำดับเช่นทูเพิลหรือรายการซึ่งกรณีนี้ให้ผลลัพธ์เหมือนกับว่าเป็นสตริง - วิธีแก้ปัญหาอื่นคือ regex ที่มีรูปแบบเป็น'\ d (? = \ D)'แต่การใช้ regex นั้นไม่จำเป็นที่นี่
eyquem

3
เพียงแค่อวดดี: stringเป็นโมดูลในไลบรารีมาตรฐานและอาจไม่ควรใช้เป็นชื่อตัวแปร docs.python.org/2/library/string.html
gak

คำตอบ:


177

stringไลบรารีของ Python มีisdigit()วิธีการ:

string[0].isdigit()

5
string โมดูลของ Python2 ไม่มีวิธีการและisdigitเป็นวิธีการstrและunicodeวัตถุ
John Machin

3
@plaes: -1 เพราะข้างบน PLUS มันขัดข้องถ้า s == ""
John Machin

4
ดูคำตอบของฉันซึ่งไม่แตกสำหรับสตริงว่าง:string[:1].isdigit()
PascalVKooten

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

ฉันไม่ใช่งูหลามบางทีคุณอาจช่วยฉันได้: ฟังก์ชันนี้จะระเบิดที่ "" string[0]หรือไม่?
corsiKa

ใช่มันจะแน่นอน คุณสามารถใช้ (string หรือ 'x') [0] .isdigit () เพื่อแก้ไขสำหรับ '' หรือ None
jcomeau_ictx

30
คุณสามารถลองstring[:1].isdigit()ซึ่งจะเลิกจัดการกับสตริงว่างอย่างมีความสุข
Simon Callan

2
เพราะนั่นไม่ใช่คำตอบของฉัน ของฉันยังดีกว่าในกรณีที่โปรแกรมเมอร์ต้องการให้มีการโยนข้อยกเว้นลงบนสตริงว่าง
jcomeau_ictx

1
@jcomeau_ictx เป๊ะเลย. ไม่เคยตั้งโปรแกรมป้องกัน หากสตริงว่างเปล่าโดยไม่คาดคิดสิ่งนี้จะผิดพลาดและไม่ควรจัดการโดยอัตโนมัติต่อไป สำนักวิชาความคิดบางแห่งบอกว่าคุณควรจัดการและจับข้อยกเว้นที่ไม่สำคัญให้เป็นคำเตือนและให้โปรแกรมดำเนินต่อไป ฉันไม่ได้มีความคิดนี้สำหรับกรณีการใช้งานส่วนใหญ่ ความเฉพาะเจาะจงในฟังก์ชั่นและโค้ดที่คุณกำลังเขียนช่วยบรรเทากรณีที่คุณต้องเขียนโค้ดป้องกันบ่อยขึ้น
jamescampbell

10

บางครั้งคุณสามารถใช้ regex

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

โอเวอร์คิล! ทำไมต้องใช้ re เมื่อคุณสามารถทำได้ใน bultins
Jakob Bowyer

1
@JakobBowyer อย่างน้อยก็น่ารู้เกี่ยวกับเรื่องนี้! แม้ว่าในกรณีนี้ใช่ regexes จะ overkill ถ้าบิวด์อินบางตัวสามารถทำได้เช่นเดียวกัน
jeromej

8

รหัสของคุณใช้ไม่ได้ คุณต้องแทนor||

ลอง

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

หรือ

strg[:1] in '0123456789'

หรือหากคุณกำลังบ้าจริงๆstartswith,

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

ผมจะได้ upvoted คุณถ้ามีเพียงแก้ปัญหาด้วยstartswith (ก tuple) แต่การแก้ปัญหาด้วยการstrg[:1]มีสองความไม่สะดวกที่พวกเขาไม่ได้เพิ่มข้อผิดพลาดหากsอาจเกิดขึ้นจะเป็นรายการของสตริงและพวกเขาผลิตTrueถ้าสตริงเริ่มต้นด้วยตัวเลขหลาย
eyquem

@eyquem พวกเขาสร้าง True ถ้าสตริงขึ้นต้นด้วย SEVERAL หลักดังนั้น? คำตอบอื่น ๆ ไม่ได้ตรวจสอบเพราะไม่ใช่ข้อกำหนดที่จะต้องตรวจสอบว่าอักขระอื่นไม่ใช่ตัวเลข
Rob Grant

ฉันamบ้าstartswithและไม่ใช้วิธีนี้ในรหัสของฉัน ขอขอบคุณ.
jamescampbell

อีกหนึ่งจุดเริ่มต้นด้วยความเป็นไปได้ ...startswith(tuple(str(i) for i in range(10)))
Jérôme

5

น่าแปลกที่หลังจากผ่านไปนานแล้วยังมีคำตอบที่ดีที่สุดหายไป

ข้อเสียของคำตอบอื่น ๆ คือการใช้[0]เพื่อเลือกอักขระตัวแรก แต่ตามที่ระบุไว้สิ่งนี้จะแบ่งสตริงว่าง

การใช้สิ่งต่อไปนี้หลีกเลี่ยงปัญหานี้และในความคิดของฉันให้ไวยากรณ์ที่สวยที่สุดและอ่านง่ายที่สุดของตัวเลือกที่เรามี นอกจากนี้ยังไม่นำเข้า / รบกวน regex ด้วย):

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

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

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
ที่น่าเกลียด. ใช้s[:1].isdigit()หรือs and s[0].isdigit()
John Machin

1
@John Machin คำว่า 'น่าเกลียด' หมายความว่าอย่างไร? อ่านไม่ออก? ฉันไม่พบข้อเสนอของคุณที่ด้านบนอ่านได้มากขึ้น s and s[0].isdigit()ยังอ่านได้น้อยกว่าในความคิดของฉัน โดยส่วนตัวแล้วฉันชอบโครงสร้าง... ถ้า ... อื่น ...จากคำพูดของคุณฉันจะปรับปรุงให้ดีขึ้นเช่นนั้น:s[0].isdigit() if s!="" else False
eyquem


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เป็นโครงสร้างงูใหญ่พิเศษและมันเป็นชนิดของเรียบร้อย: เปรียบเทียบ1 < 2 < 3(จริง) และ1 < 3 < 2(เท็จ) และ(1 < 3) < 2(จริง) นี้ไม่ได้เป็นวิธีการทำงานในภาษาอื่น ๆ มากที่สุด..)

ใช้นิพจน์ทั่วไป :

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) สูญเสีย^ใน regex
John Machin

0

คุณสามารถใช้การแสดงออกปกติ

คุณสามารถตรวจจับตัวเลขโดยใช้:

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

พาร์ [0-9] จะจับคู่ตัวเลขใด ๆ และ yourstring [: 1] จะจับคู่อักขระตัวแรกของสตริงของคุณ



-5

ลองสิ่งนี้:

if string[0] in range(10):

นี่ใช้ไม่ได้เลย range(10)สร้างรายการจำนวนเต็มในขณะที่string[0]สตริงความยาว 1
Petri Lehtinen

1
ที่ไม่ทำงาน; ประเภทไม่ตรงกัน แต่: if string[0] in map(str,range(10))ทำงาน
phynfo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.