2010-03-04 25 views

Trả lời

29
>>> s = " xyz" 
>>> len(s) - len(s.lstrip()) 
3 
+0

câu trả lời hay ^; – Pablo

+2

Nếu s dài và tiền tố khoảng trống ngắn, các giải pháp khác (các giải pháp không tạo ra một bản sao tạm thời gần như s, lấy độ dài của nó và sau đó ném đối tượng tạm thời) có thể thích hợp hơn. –

4
>>> next(i for i, j in enumerate(' xyz') if j.strip()) 
3 

hoặc

>>> next(i for i, j in enumerate(' xyz') if j not in string.whitespace) 
3 

trong các phiên bản của Python < 2.5 bạn sẽ phải làm:

(...).next() 
+0

tiếp theo không có sẵn trong 2.5, nhưng từ 2.6 trở lên, phải không? – Pablo

+0

@Pablo: đó là lý do tại sao tôi đã trình bày cách thực hiện điều này bằng '.next()' – SilentGhost

+0

'blah.strip() 'và' blah.isspace() 'hoạt động OK với Unicode; string.whitespace bị đóng băng trong thế kỷ trước. –

-1
>>> string = " xyz" 
>>> next(idx for idx, chr in enumerate(string) if not chr.isspace()) 
3 
+0

-1 vì nó không thành công cho bất kỳ chuỗi trắng khoảng trắng nào ... ** Lỗi "StopIteration:" ** được xuất trong trường hợp đó – kmonsoor

-1
>>> string = " xyz" 
>>> map(str.isspace,string).index(False) 
3 
+0

-1 vì nó không thành công cho bất kỳ chuỗi khoảng trắng nào ... :( ** " ValueError: False không có trong danh sách "** – kmonsoor

2

Hình như "regexes có thể làm bất cứ điều gì" lữ đoàn đã đưa ra những ngày nghỉ, vì vậy tôi sẽ điền vào:

>>> tests = [u'foo', u' foo', u'\xA0foo'] 
>>> import re 
>>> for test in tests: 
...  print len(re.match(r"\s*", test, re.UNICODE).group(0)) 
... 
0 
1 
1 
>>> 

FWIW: thời gian thực hiện là O (the_answer), không phải O (len (input_string))

0
import re 
def prefix_length(s): 
    m = re.match('(\s+)', s) 
    if m: 
     return len(m.group(0)) 
    return 0 
+0

" "" Hãy chắc chắn rằng mã của bạn "không làm gì" một cách duyên dáng. "" "- được gán cho Jon Bentley IIRC. –

+0

Tha thứ cho tôi sự thiếu hiểu biết của tôi, nhưng ai là anh ấy? – Pablo

+1

Vô minh là có thể tha thứ không muốn sử dụng công cụ tìm kiếm là một vấn đề khác ;-) http://en.wikipedia.org/wiki/Jon_Bentley –

1

Nhiều giải pháp trước đây đang lặp lại ở một vài điểm trong các giải pháp được đề xuất của chúng. Và một số tạo bản sao của dữ liệu (chuỗi). re.match(), strip(), enumerate(), isspace() đang nhân đôi đằng sau công việc cảnh.

next(idx for idx, chr in enumerate(string) if not chr.isspace()) 
next(idx for idx, chr in enumerate(string) if not chr.whitespace) 

là lựa chọn tốt để thử nghiệm các chuỗi so với các loại khoảng trắng hàng đầu khác nhau như các tab dọc và như vậy, nhưng cũng bổ sung thêm chi phí.

Tuy nhiên, nếu chuỗi của bạn chỉ sử dụng ký tự khoảng trống hoặc thẻ tab thì giải pháp cơ bản, giải pháp rõ ràng và nhanh hơn sau đây sẽ sử dụng ít bộ nhớ hơn.

def get_indent(astr): 

    """Return index of first non-space character of a sequence else False.""" 

    try: 
     iter(astr) 
    except: 
     raise 

    # OR for not raising exceptions at all 
    # if hasattr(astr,'__getitem__): return False 

    idx = 0 
    while idx < len(astr) and astr[idx] == ' ': 
     idx += 1 
    if astr[0] <> ' ': 
     return False 
    return idx 

Mặc dù điều này có thể không phải là tuyệt đối nhanh nhất hoặc trực quan đơn giản nhất, một số lợi ích với giải pháp này là bạn có thể dễ dàng chuyển này sang các ngôn ngữ và phiên bản của Python khác. Và có khả năng dễ nhất để gỡ lỗi, vì có ít hành vi ma thuật. Nếu bạn đặt thịt của hàm trong dòng với mã của bạn thay vì trong một hàm bạn sẽ loại bỏ phần gọi hàm và sẽ làm cho giải pháp này tương tự như mã byte cho các giải pháp khác.

Ngoài ra, giải pháp này cho phép có nhiều biến thể hơn. Chẳng hạn như thêm thử nghiệm cho các tab

or astr[idx] == '\t': 

Hoặc bạn có thể kiểm tra toàn bộ dữ liệu dưới dạng có thể lặp lại thay vì kiểm tra xem mỗi dòng có thể lặp lại hay không. Hãy nhớ những thứ như "" [0] đặt ra một ngoại lệ trong khi "" [0:] thì không.

Nếu bạn muốn thúc đẩy giải pháp cho nội tuyến bạn có thể đi theo con đường phi Pythonic:

i = 0 
while i < len(s) and s[i] == ' ': i += 1 

print i 
3 

. .

Các vấn đề liên quan