2009-08-22 32 views

Trả lời

20

Tôi đồng ý với những người khác rằng việc bắt đầu có thể đọc được nhiều hơn và bạn nên sử dụng điều đó. Điều đó nói rằng, nếu hiệu suất là một vấn đề lớn đối với một trường hợp đặc biệt như vậy, điểm chuẩn nó:

$ python -m timeit -s 'text="foo"' 'text.startswith("a")' 
1000000 loops, best of 3: 0.537 usec per loop 

$ python -m timeit -s 'text="foo"' 'text[0]=="a"' 
1000000 loops, best of 3: 0.22 usec per loop 

Vì vậy text[0] là amost 2,5 lần càng nhanh - nhưng đó là một hoạt động khá nhanh; bạn sẽ tiết kiệm được ~ 0,3 micro giây mỗi lần so sánh tùy thuộc vào hệ thống. Trừ khi bạn đang làm hàng triệu so sánh trong một tình huống quan trọng thời gian mặc dù, tôi vẫn sẽ đi với startwith dễ đọc hơn.

27

text[0] thất bại nếu text là một chuỗi rỗng:

IronPython 2.6 Alpha (2.6.0.1) on .NET 4.0.20506.1 
Type "help", "copyright", "credits" or "license" for more information. 
>>> text = "" 
>>> print(text.startswith("a")) 
False 
>>> print(text[0]=='a') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: index out of range: 0 

EDIT: Bạn nói bạn "biết" rằng text là không có sản phẩm nào ... làm thế nào tự tin là bạn về điều đó, và những gì bạn muốn xảy ra nếu nó trống trong thực tế? Nếu lỗi phù hợp (ví dụ: có nghĩa là lỗi trong mã của bạn) sẽ khuyến khích sử dụng text[0]=='a'.

câu hỏi khác:

  • Làm thế nào quan tâm là bạn về việc thực hiện điều này? Nếu đây là hiệu suất quan trọng, thì hãy chuẩn hóa nó trên thời gian chạy Python cụ thể của bạn. Tôi sẽ không được hoàn toàn ngạc nhiên khi thấy rằng (nói) một hình thức nhanh hơn trên IronPython và một hình thức khác nhanh hơn trên CPython.

  • Làm bạn (và nhóm của bạn) tìm thấy dễ đọc hơn?

+0

Rất tiếc, tôi không nói rằng tôi biết rằng văn bản đó không trống. – dugres

+4

@Jon Skeet: Đúng, nhưng điều đó có thể được sử dụng để nói "văn bản [: 1]" thay thế. – balpha

+0

@balpha: Nhưng đó là một câu hỏi khác rồi :) –

10

Cá nhân tôi sẽ nói startswith dễ đọc hơn.

Ngoài ra, từ Python 2.5 startwith có thể mất một tuple các tiền tố để tìm kiếm:

>>> "hello world".startswith(("hello","goodbye")) 
True 
10

Có: nó dễ dàng hơn để sử dụng và dễ đọc hơn. Khi bạn đang thử nghiệm cho nhiều hơn một lá thư, khi sử dụng cắt, bạn sẽ phải biết làm thế nào dài văn bản mục tiêu là:

haystack = 'Hello, World!' 
needle = 'Hello' 

# The easy way 
result = haystack.startswith(needle) 

# The slightly harder way 
result = haystack[:len(needle)] == needle 

Edit: Câu hỏi đặt ra dường như đã thay đổi. Nó bây giờ nói, "biết văn bản không phải là trống rỗng và chúng tôi chỉ quan tâm đến nhân vật đầu tiên của nó." Điều đó biến nó thành một tình huống giả định khá vô nghĩa.

Tôi nghi ngờ người hỏi đang cố gắng "tối ưu hóa" mã của họ để thực hiện tốc độ. Nếu đúng như vậy, câu trả lời của tôi là: không. Sử dụng bất kỳ hình thức nào là nhiều hơn có thể đọc được và do đó, có thể duy trì được nhiều hơn khi bạn phải quay lại và làm việc với nó sau một năm kể từ bây giờ. Chỉ tối ưu hóa nếu hồ sơ cho thấy dòng mã là nút cổ chai. Đây không phải là một số thuật toán O (n²). Đó là so sánh chuỗi.

+0

Câu hỏi thực sự là về việc kiểm tra chữ cái đầu tiên. – dugres

+3

Tôi đã nhấn vấn đề chính xác này trong trường hợp sử dụng phi giả định; có hiệu quả tôi đã có một bản đồ mà proxy vào một từ điển nếu bạn yêu cầu một khóa bắt đầu với ~, và một từ điển khác cho mỗi nhân vật khác. Nó được gọi là hàng chục ngàn đến hàng triệu lần, và đặc biệt được gọi là vẽ lại các phần bẩn của một cửa sổ khi một con chuột di chuyển qua nó (cột mô hình danh sách ảo GTK +), vì vậy nó cần phải cực kỳ hiệu quả. Vì tôi không biết chuỗi không trống, tôi đã sử dụng [: 1]; như được đề xuất bên dưới, nó vẫn nhanh gấp hai lần startsWith. –

5

Cụm từ cổ phiếu cho questiom là: "Tối ưu hóa sớm là gốc rễ của mọi điều ác".

+3

Vì vậy, bạn sẽ sử dụng cái nào? – dugres

+3

text.startswith ('a'). Nó nói rõ ràng những gì bạn muốn đạt được. Tôi chỉ có thể nghĩ về văn bản [0] == 'a' làm phương án thay thế, như một cách để tiết kiệm một vài chu trình CPU. – Zed

+1

Báo giá chọn lọc. Đọc toàn bộ đoạn trong đó mệnh đề đó được nhúng. Nó không phải là một câu hoàn chỉnh trong bản gốc. – EJP

1

văn bản [0] == 'a' được xem là hiệu suất tốt. Ngoài ra, bạn cần thêm xác nhận khi bạn sử dụng tính năng này.

5

text[0] có thể không thành công nhưng tương đương text[:1] là an toàn nếu chuỗi trống.

Nếu bạn muốn so sánh nhiều hơn một ký tự, tôi tin rằng .startswith() là tốt hơn.

7

PEP 8 dứt khoát nói để sử dụng startswith, vì khả năng đọc:

- Use ''.startswith() and ''.endswith() instead of string 

cắt để kiểm tra cho các tiền tố hoặc hậu tố.

startswith() and endswith() are cleaner and less error prone. For 
    example: 

    Yes: if foo.startswith('bar'): 

    No: if foo[:3] == 'bar': 
2
def compo2(): 
    n = "abba" 
    for i in range(1000000): 
     n[:1]=="_" 

nhanh hơn

def compo(): 
    n = "abba" 
    for i in range(1000000): 
     n.startswith("_") 

cProfile báo cáo 0,061 cho compo2 so với 0,954 cho compo trên máy tính của tôi. Điều này quan tâm trong trường hợp bạn muốn thực hiện rất nhiều tiền tố kiểm tra cho "_mystring" khác nhau. Nếu hầu hết các chuỗi không bắt đầu bằng dấu gạch dưới thì sử dụng string[:1]== char trước khi sử dụng startswith là một tùy chọn để tối ưu hóa mã của bạn. Trong ứng dụng thực, phương pháp này đã tiết kiệm cho tôi khoảng 15% thời gian cpu.

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