2011-12-24 26 views

Trả lời

8
v = [1,2,3,4,3,1,2] 
any([2,3] == v[i:i+2] for i in xrange(len(v) - 1)) 

Trong khi phiên bản @ PaoloCapriotti của hiện các trick, chương trình này là nhanh hơn, bởi vì nó dừng lại phân tích các v càng sớm càng hợp được tìm thấy.

+1

Sẽ không có người nối tạo ra một sublist mới mỗi lần? wont 2 nếu được tốt hơn? đúng nếu tôi đã sai lầm. – st0le

+0

Tôi tin rằng 'v [i: i + 2]' chỉ xem các phần tử của danh sách. – eumiro

+2

@eumiro Niềm tin của bạn không chính xác :-) Danh sách lát tạo danh sách mới. Ví dụ, đó là cơ chế đằng sau thành ngữ để tạo một bản sao danh sách: '' c = s [:] ''. –

2
[2, 3] in [v[i:i+2] for i in range(len(v) - 1)] 
1

Nói chung không thể lặp lại tất cả các giá trị. Sau cùng, danh sách một nghìn phần tử có thể kết thúc bằng [.., 2, 3].

Trong trường hợp đặc biệt, có các phím tắt. Các giá trị luôn được đặt hàng và bạn có luôn tìm kiếm một giá trị cụ thể không? Nếu có, bạn có thể, ví dụ: sử dụng tìm kiếm nhị phân để tìm giá trị và sau đó so sánh nó với giá trị tiếp theo. Nếu các giá trị không có thứ tự, không có phím tắt. Nếu bạn đang tìm kiếm bất kỳ hai giá trị tiếp theo nào, thì không có lối tắt nào. Đối với trường hợp ở giữa, có thể có một phím tắt.

3

Đây có lẽ là một chút của một vòng về cách để làm điều đó, nhưng bạn có thể sử dụng (với v biến của bạn ở trên):

' 2, 3' in str(v) 
+5

Bạn có chắc chắn rằng mẫu "12, 3" không tồn tại? – DSM

+1

@ uosɐſ: bạn đã chỉnh sửa câu trả lời để bao gồm thêm không gian để cố gắng tránh sự cố mà tôi đã chỉ ra, nhưng nó vẫn không hoạt động. Phiên bản của bạn sẽ không khớp với 2,3 ngay tại đầu chuỗi (vì ký tự trước số 2 sẽ là [, không phải là dấu cách). – DSM

+1

Tôi rất tiếc khi chỉnh sửa nó. 1) nó không phải là của tôi để chỉnh sửa, tôi đã chỉ kích hoạt hạnh phúc, 2) nó screwed lên bình luận của bạn, 3) nó không phải là một giải pháp hiệu quả. Nhưng để đáp ứng với bình luận của bạn ở đây, cách thức mà danh sách được chuyển đổi thành một chuỗi quan trọng ở đây, vâng. Nếu có một không gian hàng đầu và không có dấu ngoặc nó sẽ làm việc. –

1

Bạn sẽ cần một vòng lặp.

Không giống như chuỗi Python hỗ trợ kiểm tra sau đó bằng cách sử dụng toán tử trong, danh sách Python không có kiểm tra sau được tạo sẵn.

0

Nếu viết danh sách xảy ra ít thường xuyên hơn đọc từ nó, có lẽ bạn có thể xây dựng một cây tiền tố khi viết. [1] sẽ có một nút con [2], [2] sẽ có [3] và [3] a [4]. Với một bộ dữ liệu phức tạp hơn, cây sẽ hữu ích hơn. Nó sẽ có độ sâu 2 trong trường hợp của bạn và sẽ được lập chỉ mục trên phần tử ban đầu trong chuỗi tìm kiếm của bạn.

Bạn vẫn muốn truy cập từng nút, nhưng chỉ một lần cho vòng đời của chuỗi tìm kiếm, nếu chỉ nối thêm. Khi bạn chắp thêm một phần tử, bạn sẽ cập nhật cây để bao gồm phần tử con nếu không có. Sau đó, số lần đọc được giảm xuống tối đa O (2 * k) trong đó k là số phần tử duy nhất. Trong trường hợp các chữ số, đó là 20 lần đọc tối đa để kiểm tra xem một chuỗi có nằm trong danh sách hay không.

Lợi thế tốc độ xuất phát từ việc precomputing độ dài-2 sau đó danh sách chứa và xóa các bản sao. Nó cũng có vảy tốt với độ dài dài hơn. O (độ sâu * k) trường hợp xấu nhất. Thậm chí tốt hơn nếu hashtables được sử dụng.

2
v = [1,2,3,4,3,1,2] 

def find(x,y,v): 
     return (x,y) in zip(v,v[1:]) 

print find(2,3,v) 
print find(1,4,v) 
0

Tôi biết bạn đã hài lòng với một trong những câu trả lời trong bài viết này, nhưng bạn có thể thử với những sản phẩm sau

>>> v = [1,2,3,4,3,1,2] 
def InList(v,(i,j)): 
    start=1 
    try: 
     while True: 
      if v[v.index(i,start)+1]==j and v[v.index(j,start)-1]==i: 
       return True 
      start=v.index(i)+1 
    except IndexError: 
     return False 
    except ValueError: 
     return False 


>>> InList(v,(2,3)) 
True 
>>> InList(v,(4,5)) 
False 
>>> InList(v,(1,2)) 
True 
>>> InList(v,(12,2)) 
False 
>>> InList(v,(3,1)) 
True 

Ok Curiosity trở nên tốt hơn của tôi và vì vậy muốn kiểm tra cách thực hiện điều này thực hiện thực hiện với việc thực hiện đăng tải nhanh nhất

>>> stmt1=""" 
v = [1,2,3,4,3,1,2] 
def InList(v,(i,j)): 
    start=1 
    try: 
     while True: 
      if v[v.index(i,start)+1]==j and v[v.index(j,start)-1]==i: 
       return True 
      start=v.index(i)+1 
    except IndexError: 
     return False 
    except ValueError: 
     return False 
InList(v,(2,3)) 
InList(v,(4,5)) 
InList(v,(1,2)) 
InList(v,(12,2)) 
""" 
>>> stmt2=""" 
v = [1,2,3,4,3,1,2] 
def InList(v,(x,y)): 
    any([x,y] == v[i:i+2] for i in xrange(len(v) - 1)) 
InList(v,(2,3)) 
InList(v,(4,5)) 
InList(v,(1,2)) 
InList(v,(12,2)) 
""" 
>>> t1=timeit.Timer(stmt=stmt1) 
>>> t2=timeit.Timer(stmt=stmt2) 
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000) 
13.67 usec/pass 
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000) 
20.67 usec/pass 
>>> 

Gosh đây là cách nhanh

Lưu ý ** Cảm ơn Michael đã chỉ ra. Tôi đã sửa chữa nó và đây là giải pháp cập nhật của tôi.

+0

Điều này sẽ không hoạt động nếu có một ví dụ về (i, _not j_) trước '(i, j)'. –

+0

@MichaelHoffman, Cảm ơn bạn rất nhiều vì đã chỉ ra. Tôi đã sửa chữa nó. Bạn có thể không có một cái nhìn. – Abhijit

0

Câu trả lời của eumiro giành được sự thanh lịch, nhưng nếu bạn cần một cái gì đó nhanh hơn, bạn có thể tận dụng phương pháp được xây dựng trong list.index() giúp tiết kiệm thời gian trong việc lặp lại toàn bộ danh sách.

v = [1,2,3,4,3,1,2] 

def f1(items): 
    return any([2,3] == v[i:i+2] for i in xrange(len(v) - 1)) 

def f2(items): 
    i = 0 
    index = items.index 
    try: 
     while 1: 
      i = index(2, i) + 1 
      if items[i] == 3: 
       return True 
    except IndexError: 
     return False 

from timeit import repeat  
print "f1", min(repeat("f1(v)", "from __main__ import f1, v", number=1000)) 
print "f2", min(repeat("f2(v)", "from __main__ import f2, v", number=1000)) 

Khi tôi chạy này, tôi nhận được:

f1 0.00300002098083 
f2 0.0 

này cần được nhanh hơn khi trận đấu không phải là quá gần đầu danh sách.

1

Bạn có thể sử dụng Boyer-Moore algorithm để tăng tốc hoàn toàn không cần thiết. Các trường hợp chung là một chút khó khăn, nhưng nó đơn giản nếu bạn chỉ tìm kiếm một cặp.

def find_pair(seq, a, b): 
    i = 1 
    while i < len(seq): 
     if seq[i] == b and seq[i - 1] == a: return i - 1 
     i += 2 - (seq[i] == a) 

print find_pair([1, 5, 3, 4, 3, 1, 2, 3, 3], 2, 3) 
+0

Trong hầu hết các trường hợp, tốc độ của 'list.index()' được xây dựng sẵn của Python sẽ áp đảo mọi lợi ích thu được bằng cách triển khai Boyer-Moore bằng Python thuần túy. –

+0

Đúng, câu trả lời này là một loại trò đùa :) –

2

Có lẽ thậm chí đơn giản hơn:

a = range(100) 
exists = (55,56) in zip(a, a[1:]) 
Các vấn đề liên quan