Tôi cố gắng để thực hiện điều này hiệu quả càng tốt.
Sử dụng trình tạo; những người không quen thuộc với những con thú này nên kiểm tra their documentation và của yield expressions.
Về cơ bản, nó tạo ra một trình tạo các giá trị từ chuỗi có thể được đặt lại bằng cách gửi nó một giá trị thực. Nếu máy phát lại được đặt lại, nó sẽ bắt đầu lại từ đầu sub
.
Sau đó, nó chỉ so sánh các giá trị kế tiếp của sequence
với năng suất máy phát, đặt lại trình tạo nếu chúng không khớp.
Khi máy phát hết giá trị, nghĩa là đến cuối sub
mà không bị đặt lại, điều đó có nghĩa là chúng tôi đã tìm thấy kết quả phù hợp.
Vì nó hoạt động cho bất kỳ chuỗi nào, bạn thậm chí có thể sử dụng nó trên chuỗi, trong trường hợp nó hoạt động tương tự như str.find
, ngoại trừ nó trả về False
thay vì -1
.
Lưu ý thêm: Tôi nghĩ rằng giá trị thứ hai của bộ trả về phải phù hợp với tiêu chuẩn Python, thường là cao hơn. tức là "string"[0:2] == "st"
. Nhưng spec nói khác, vì vậy đó là cách làm việc này.
Nó phụ thuộc vào việc này có phải là một thói quen có mục đích chung hay không hoặc nó có thực hiện một số mục tiêu cụ thể hay không; trong trường hợp sau nó có thể tốt hơn để thực hiện một thói quen có mục đích chung và sau đó bọc nó trong một chức năng mà twiddles giá trị trả lại cho phù hợp với spec.
def reiterator(sub):
"""Yield elements of a sequence, resetting if sent ``True``."""
it = iter(sub)
while True:
if (yield it.next()):
it = iter(sub)
def find_in_sequence(sub, sequence):
"""Find a subsequence in a sequence.
>>> find_in_sequence([2, 1], [-1, 0, 1, 2])
False
>>> find_in_sequence([-1, 1, 2], [-1, 0, 1, 2])
False
>>> find_in_sequence([0, 1, 2], [-1, 0, 1, 2])
(1, 3)
>>> find_in_sequence("subsequence",
... "This sequence contains a subsequence.")
(25, 35)
>>> find_in_sequence("subsequence", "This one doesn't.")
False
"""
start = None
sub_items = reiterator(sub)
sub_item = sub_items.next()
for index, item in enumerate(sequence):
if item == sub_item:
if start is None: start = index
else:
start = None
try:
sub_item = sub_items.send(start is None)
except StopIteration:
# If the subsequence is depleted, we win!
return (start, index)
return False
Đối với những gì nó có giá trị, trở về '[bắt đầu, kết thúc + 1]' là pythonic hơn vì nó trông giống như một lát - '(end + 1) -start' cho chiều dài của những gì được tìm thấy . –
Điều này trông giống như một thiết kế xấu - đôi khi hàm trả về một bool, đôi khi nó trả về một danh sách. Điều đó làm cho nó rất khó sử dụng vì bạn phải kiểm tra kiểu trả về trước khi bạn có thể làm bất cứ điều gì với kết quả. IMHO một hàm có tên "contains" chỉ trả về True hoặc False. –
Thật đáng buồn khi các danh sách không có chức năng cần thiết tích hợp sẵn, nhưng các chuỗi làm ('str.find'). –