Dizenin Python ile bir sayı ile başlayıp başlamadığını nasıl anlarım?


91

Bir sayı ile başlayan bir dizem var (0-9 arası) Yapabileceğimi biliyorum "veya" startswith () kullanan 10 test vakası ama muhtemelen daha düzgün bir çözüm var

yani yazmak yerine

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

Daha akıllı / daha verimli bir yol var mı?


Soru sorulursa: "Bu çok tekrarlı mı?", Muhtemelen - yüksek seviyeli bir dilde - cevap "Neden, evet, kesinlikle öyle" dir. Tembel ol!

42
Iskaladın string.startswith('1').
MAK

2
@Illusionist Yazıldığı gibi, sorunuz sadece bir basamakla başlayan dizeleri tespit etmek istediğiniz anlamına geliyor. Eğer öyleyse, aşağıdaki olanlar arasında sadece doğru cevabı kullanılarak olanlar değildir s[0]ya s[:1]ama John Machin çözümü: if s.startswith(tuple('0123456789')). Dahası, bu çözüm, s'nin bir tuple veya list gibi bir dizi olması durumunda hataya neden olur ve bu durumlar bir dizeymiş gibi aynı sonucu verir. - Başka bir çözüm, deseni '\ d (? = \ D)' olan bir normal ifadedir, ancak burada normal ifadenin kullanımı gereksizdir.
eyquem

3
Sadece bilgiçlik taslamak: stringstandart kitaplıktaki bir modüldür ve muhtemelen değişken adı olarak kullanılmamalıdır. docs.python.org/2/library/string.html
gak

Yanıtlar:


170

Python'un stringkütüphanesinde şu isdigit()yöntem vardır:

string[0].isdigit()

5
Python2 string modülünün yöntemleri yoktur ve isdigitbir yöntem strve unicodenesnelerdir.
John Machin

3
@plaes: -1 Yukarıdaki PLUS nedeniyle, s == "" ise çöküyor
John Machin

3
Boş bir dizge için kırılmayan string[:1].isdigit()
cevabıma bakın

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

Ben bir python adamı değilim, bu yüzden belki bana bu konuda yardımcı olabilirsiniz: bu işlev "" üzerine bomba atacak string[0]mı?
corsiKa

evet, kesinlikle olacak. '' veya None için düzeltmek için (string veya 'x') [0] .isdigit () kullanabilirsiniz
jcomeau_ictx

30
string[:1].isdigit()Boş bir dizeyle mutlu bir şekilde çıkacak olan deneyebilirsiniz .
Simon Callan

2
çünkü bu benim cevabım değil; programcının boş bir dizgeye bir istisna atılmasını istemesi durumunda benimki daha iyidir.
jcomeau_ictx

1
@jcomeau_ictx tam olarak doğru. asla savunma amaçlı program yapmayın. dize beklenmedik boş kalıyorsa o olmalıdır dışarı hata ve otomatik zaten ele alınmamalıdır. Bazı düşünce okulları, uyarı olarak kritik olmayan istisnaları incelikle ele almanız ve yakalamanız ve programı devam ettirmeniz gerektiğini söylüyor. Çoğu kullanım durumu için bu zihniyetten değilim. Yazdığınız işlevler ve koddaki özgüllük, daha sık defansif kodlama yapmanız gereken uç durumların azaltılmasına yardımcı olur.
jamescampbell

10

bazen normal ifadeyi kullanabilirsiniz

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

aşırı yükleme! Bultins yapabilecekken neden re kullanıyorsunuz
Jakob Bowyer

1
@JakobBowyer En azından bunu bilmek güzel! Bu durumda bile, evet, bazı yerleşikler aynı şeyi yapabiliyorsa normal ifadeler aşırı derecede öldürür.
jeromej

8

Kodunuz çalışmayacak; oryerine ihtiyacın var ||.

Deneyin

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

veya

strg[:1] in '0123456789'

veya gerçekten deli iseniz startswith,

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

Sadece startswith (tuple) ile bir çözüm olsaydı, size olumlu oy verirdim . Ancak çözümlerin strg[:1]iki sakıncası vardır: eğer s dizgelerin bir listesi olabilirse bir hata oluşturmazlar ve dizi SEVERAL basamakla başlıyorsa True üretirler .
eyquem

@eyquem dize BİRKAÇ basamağı ile başlıyorsa onlar Doğru üretmek Yani? Diğer cevaplar bunu kontrol etmez, çünkü diğer karakterlerin sayısal olmadığını kontrol etmek zorunda kalması bir gereklilik değildi.
Rob Grant

Ben değilim deli startswithve bildiğim kodunda bu yöntemi uygulayan yaptı. Teşekkür ederim.
jamescampbell

Olasılıkla bir başlangıç ​​daha ...startswith(tuple(str(i) for i in range(10)))
Jérôme

4

Bu kod parçası:

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

aşağıdakileri yazdırır:

fukushima            False
123 is a number      True
                     False

4
Bu çirkin. s[:1].isdigit()Veya kullanıns and s[0].isdigit()
John Machin

1
@John Machin 'çirkin' derken neyi kastediyorsunuz? Okunamaz ? Önerilerinizi yukarıda daha okunabilir bulmuyorum. s and s[0].isdigit()bence daha az okunabilir. Şahsen ben yapıyı beğendim ... if ... else ...s[0].isdigit() if s!="" else False
Yorumunuzu

3

Bu kadar uzun bir süre sonra hala en iyi cevabın eksik olması şaşırtıcı.

Diğer cevapların dezavantajı [0], ilk karakteri seçmek için kullanmaktır , ancak belirtildiği gibi, bu, boş dizede kırılır.

Aşağıdakileri kullanmak bu sorunu ortadan kaldırır ve bence elimizdeki seçeneklerin en güzel ve en okunabilir sözdizimini verir. Ayrıca normal ifadeyi içe aktarmaz / rahatsız etmez):

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

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

2

Ayrıca şunları da kullanabilirsiniz try...except:

try:
    int(string[0])
    # do your stuff
except:
    pass # or do your stuff

1

İşte "cevaplarım" (burada benzersiz olmaya çalışıyorum, aslında bu özel durum için ikisini de önermiyorum :-)

Kullanma ord () veözel a <= b <= cform:

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

(Bu a <= b <= c, tıpkı a < b < cözel bir Python yapısıdır ve oldukça düzgündür: karşılaştırma 1 < 2 < 3(doğru) ve 1 < 3 < 2(yanlış) ve (1 < 3) < 2(doğru). Diğer birçok dilde böyle çalışmaz.)

Normal ifade kullanma :

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) Normal ifadede ord()(2) 'yi kaybedin ^.
John Machin

0

Normal ifadeler kullanabilirsiniz .

Aşağıdakileri kullanarak rakamları tespit edebilirsiniz:

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

[0-9] par değeri herhangi bir rakamla eşleşir ve dizeniz [: 1] dizenizin ilk karakteriyle eşleşir



-5

Bunu dene:

if string[0] in range(10):

Bu hiç çalışmıyor. range(10)tamsayıların bir listesini üretir, oysa string[0]uzunluk 1 olan bir dizedir.
Petri Lehtinen

1
Bu işe yaramıyor; türler eşleşmiyor. Ama: if string[0] in map(str,range(10))çalışır
phynfo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.