Tìm kiếm nhị phân (chia đôi) trong Python


176

Có chức năng thư viện nào thực hiện tìm kiếm nhị phân trong danh sách / tuple và trả về vị trí của mục nếu tìm thấy và 'Sai' (-1, Không, v.v.) nếu không?

Tôi đã tìm thấy các hàm bisect_left / right trong mô-đun bisect , nhưng chúng vẫn trả về một vị trí ngay cả khi mục không có trong danh sách. Điều đó hoàn toàn tốt cho mục đích sử dụng của họ, nhưng tôi chỉ muốn biết liệu một mục có trong danh sách hay không (không muốn chèn bất cứ điều gì).

Tôi đã nghĩ đến việc sử dụng bisect_leftvà sau đó kiểm tra xem mục ở vị trí đó có bằng với những gì tôi đang tìm kiếm hay không, nhưng điều đó có vẻ rườm rà (và tôi cũng cần kiểm tra giới hạn nếu số đó có thể lớn hơn số lớn nhất trong danh sách của tôi không). Nếu có một phương pháp đẹp hơn tôi muốn biết về nó.

Chỉnh sửa Để làm rõ những gì tôi cần điều này: Tôi biết rằng một từ điển sẽ rất phù hợp cho việc này, nhưng tôi đang cố gắng giữ mức tiêu thụ bộ nhớ càng thấp càng tốt. Mục đích sử dụng của tôi sẽ là một loại bảng tra cứu hai chiều. Tôi có trong bảng một danh sách các giá trị và tôi cần có thể truy cập các giá trị dựa trên chỉ mục của chúng. Và tôi cũng muốn có thể tìm thấy chỉ mục của một giá trị cụ thể hoặc Không có nếu giá trị không có trong danh sách.

Sử dụng từ điển cho việc này sẽ là cách nhanh nhất, nhưng sẽ (xấp xỉ) gấp đôi yêu cầu bộ nhớ.

Tôi đã hỏi câu hỏi này vì nghĩ rằng tôi có thể đã bỏ qua một cái gì đó trong các thư viện Python. Có vẻ như tôi sẽ phải viết mã của riêng mình, như Moe đề xuất.


1
Bạn đang cố gắng đạt được điều gì? Nếu các giá trị là duy nhất, hãy xem xét sử dụng một bộ và "if value in set: Something".
Kirk Strauser

Đối với những gì nó có giá trị, "-1" được coi là đúng; "0" sẽ là sai.
Glyph

3
Tôi đã đề cập -1 vì một hàm trả về chỉ mục của mục được tìm kiếm trong mảng có thể trả về 0 vì vậy -1 được trả về nếu không tìm thấy mục đó (tương tự như tìm kiếm chuỗi con).
rslite

3
Nếu bạn sử dụng numpy, np.searchsortedlà hữu ích. docs.scipy.org/doc/numpy/reference/generated/ Kẻ
Roman Shapovalov

Câu trả lời:


237
from bisect import bisect_left

def binary_search(a, x, lo=0, hi=None):  # can't use a to specify default for hi
    hi = hi if hi is not None else len(a)  # hi defaults to len(a)   
    pos = bisect_left(a, x, lo, hi)  # find insertion position
    return pos if pos != hi and a[pos] == x else -1  # don't walk off the end

10
@volcano Nói chung binsearch cũng vậy.
cubuspl42

4
@TomSwirly không đơn giản như của bạn nhưng chính xác và vẫn là một cải tiến:if hi is None: hi = len(a)
Đánh dấu tiền chuộc

Điều gì về thứ tự giảm dần?
Parikshit Chalke

2
Bạn có thể thêm một số lời giải thích bên ngoài mã? Tiêu chuẩn ở đây đã thay đổi.
SS Anne

54

Tại sao không xem mã cho bisect_left / right và điều chỉnh nó cho phù hợp với mục đích của bạn.

như thế này:

def binary_search(a, x, lo=0, hi=None):
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        midval = a[mid]
        if midval < x:
            lo = mid+1
        elif midval > x: 
            hi = mid
        else:
            return mid
    return -1

29
Tôi ban đầu + 1'ed cái này, nhưng bây giờ tôi đã đi đến kết luận đây không phải là một điều tốt. Nếu câu trả lời này được tuân theo, nó sẽ gây ra nhiều sự trùng lặp mã và như chúng ta đều biết, thật đơn giản để tìm kiếm nhị phân tìm kiếm.
abyx

1
nó không nên hi = mid - 1ở trong elif?
Paweł Prażak

7
@ Paweł: chúng là hai biến thể tương đương, tùy thuộc vào giới hạn trên là bao gồm hay độc quyền. bạn có thể thay đổi hi = midthành hi = mid-1hi = len(a)thành hi = len(a)-1while lo < hi:thành while lo <= hi, và nó sẽ hoàn toàn chính xác
user102008

2
tại sao không làm một cái gì đó như: def binary_search (a, x, lo = 0, hi = none): i = bisect (a, x, lo, hi) trả lại i nếu a [i] == x khác -1 xin lỗi vì định dạng - không chắc chắn làm thế nào để làm điều này đúng trong phần bình luận
Vitali

1
Bạn nên sử dụng bisect.bisect_left()hơn là này.
alastair

37

Đây là một chủ đề nhỏ (vì câu trả lời của Moe có vẻ hoàn chỉnh đối với câu hỏi của OP), nhưng có thể đáng để xem xét sự phức tạp cho toàn bộ quy trình của bạn từ đầu đến cuối. Nếu bạn đang lưu trữ thứ trong một danh sách được sắp xếp (đó là nơi tìm kiếm nhị phân sẽ giúp), và sau đó chỉ cần kiểm tra sự tồn tại, bạn sẽ phải chịu (trường hợp xấu nhất, trừ khi được chỉ định):

Danh sách đã sắp xếp

  • O (n log n) để tạo danh sách ban đầu (nếu đó là dữ liệu chưa được sắp xếp. O (n), nếu được sắp xếp)
  • Tra cứu O (log n) (đây là phần tìm kiếm nhị phân)
  • O (n) chèn / xóa (có thể là trường hợp trung bình O (1) hoặc O (log n), tùy thuộc vào mẫu của bạn)

Trong khi đó với a set(), bạn đang phát sinh

  • O (n) để tạo
  • O (1) tra cứu
  • O (1) chèn / xóa

Điều mà một danh sách được sắp xếp thực sự giúp bạn là "tiếp theo", "trước đó" và "phạm vi" (bao gồm chèn hoặc xóa phạm vi), là O (1) hoặc O (| phạm vi |), được đưa ra một chỉ mục bắt đầu. Nếu bạn không sử dụng các loại hoạt động đó thường xuyên, thì lưu trữ dưới dạng bộ và sắp xếp để hiển thị có thể là một thỏa thuận tổng thể tốt hơn. set()phát sinh rất ít chi phí bổ sung trong python.


7
Có một điều khác một danh sách được sắp xếp giúp bạn. O (n) ra lệnh ngang. Với một tập hợp là O (n log n) và cuối cùng bạn phải sao chép các tham chiếu đến dữ liệu vào một danh sách.
Omnifarious

1
Đúng là đủ! Cảm ơn bạn đã mở rộng về những gì tôi có nghĩa là tìm kiếm phạm vi. Fwiw, một truyền tải đầy đủ giống như một truy vấn phạm vi giữa min, max, là O (k) trong đó k = n :)
Gregg Lind

14

Điều đáng nói là các tài liệu bisect hiện cung cấp các ví dụ tìm kiếm: http://docs.python.org/l Library / bisect.html # searching- sort-lists

(Tăng ValueError thay vì trả về -1 hoặc Không có gì là pythonic hơn - ví dụ: list.index () thực hiện điều đó. Nhưng tất nhiên bạn có thể điều chỉnh các ví dụ theo nhu cầu của mình.)


11

Đơn giản nhất là sử dụng bisect và kiểm tra lại một vị trí để xem mục đó có ở đó không:

def binary_search(a,x,lo=0,hi=-1):
    i = bisect(a,x,lo,hi)
    if i == 0:
        return -1
    elif a[i-1] == x:
        return i-1
    else:
        return -1

2
Đẹp, nhưng mã vạch nếu bạn không vượt qua giá trị 'hi'. Tôi sẽ viết nó như thế này: "def binary_search (a, x, lo = 0, hi = Không): từ bisect nhập bisect i = bisect (a, x, lo, hi hoặc len (a)) return (i- 1 nếu a [i-1] == x khác -1) "và kiểm tra nó như thế này:" cho i trong phạm vi (1, 20): a = list (phạm vi (i)) cho aa trong a: j = binary_search (a, aa) nếu j! = aa: in i, aa, j "
hughdbrown

8

Điều này đúng từ hướng dẫn:

http://docs.python.org/2/l Library / bisect.html

8.5.1. Tìm kiếm danh sách sắp xếp

Các hàm bisect () ở trên rất hữu ích để tìm các điểm chèn nhưng có thể khó sử dụng hoặc khó sử dụng cho các tác vụ tìm kiếm thông thường. Năm chức năng sau đây cho thấy cách chuyển đổi chúng thành tra cứu tiêu chuẩn cho các danh sách được sắp xếp:

def index(a, x):
    'Locate the leftmost value exactly equal to x'
    i = bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    raise ValueError

Vì vậy, với sửa đổi nhỏ, mã của bạn sẽ là:

def index(a, x):
    'Locate the leftmost value exactly equal to x'
    i = bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return -1

6

Tôi đồng ý rằng câu trả lời của @ DaveAbrahams sử dụng mô-đun bisect là cách tiếp cận chính xác. Ông không đề cập đến một chi tiết quan trọng trong câu trả lời của mình.

Từ các tài liệu bisect.bisect_left(a, x, lo=0, hi=len(a))

Mô-đun chia đôi không yêu cầu mảng tìm kiếm phải được tính toán trước. Bạn chỉ có thể trình bày các điểm cuối cho bisect.bisect_leftthay vì sử dụng mặc định của 0len(a).

Thậm chí quan trọng hơn đối với việc sử dụng của tôi, tìm kiếm một giá trị X sao cho lỗi của hàm đã cho được giảm thiểu. Để làm điều đó, tôi cần một cách để thuật toán của bisect_left gọi tính toán của tôi thay vào đó. Điều này thực sự đơn giản.

Chỉ cần cung cấp một đối tượng xác định __getitem__a

Ví dụ, chúng ta có thể sử dụng thuật toán bisect để tìm căn bậc hai với độ chính xác tùy ý!

import bisect

class sqrt_array(object):
    def __init__(self, digits):
        self.precision = float(10**(digits))
    def __getitem__(self, key):
        return (key/self.precision)**2.0

sa = sqrt_array(4)

# "search" in the range of 0 to 10 with a "precision" of 0.0001
index = bisect.bisect_left(sa, 7, 0, 10*10**4)
print 7**0.5
print index/(10**4.0)

Điều này không sạch sẽ. Sử dụng scipy.optimizecho việc này.
Neil G

4

Nếu bạn chỉ muốn xem nó có mặt hay không, hãy thử biến danh sách thành một lệnh:

# Generate a list
l = [n*n for n in range(1000)]

# Convert to dict - doesn't matter what you map values to
d = dict((x, 1) for x in l)

count = 0
for n in range(1000000):
    # Compare with "if n in l"
    if n in d:
        count += 1

Trên máy của tôi, "if n in l" mất 37 giây, trong khi "if n in d" mất 0,4 giây.


2
Điều đó không phải lúc nào cũng là một lựa chọn tốt vì một vài lý do: 1) bộ / bộ chiếm nhiều bộ nhớ hơn. 2) nếu anh ta không có nhiều trong danh sách, tìm kiếm nhị phân có thể nhanh hơn. 3) chuyển đổi danh sách thành một dict là một hoạt động O (n) trong khi tìm kiếm nhị phân là O (log n).
Jason Baker

3
Là một FYI, "tập hợp" chi phí trong python so với danh sách python, là rất rất thấp. Và họ cực kỳ nhanh chóng để tra cứu. Trong đó tìm kiếm nhị phân thực sự vượt trội là để tìm kiếm phạm vi.
Gregg Lind

Chuyển đổi danh sách có thể là O (n) nhưng sắp xếp dữ liệu trong danh sách, điều bạn phải làm trước khi tìm kiếm nhị phân, thì tệ hơn. Dữ liệu đến từ đâu, có lẽ bạn có thể chèn nó vào từ điển khi bạn đi. Tôi đồng ý rằng bộ nhớ có thể là một vấn đề.
Mark Baker

4

Đây là:

  • không đệ quy (làm cho nó hiệu quả hơn bộ nhớ so với hầu hết các cách tiếp cận đệ quy)
  • thực sự làm việc
  • nhanh vì nó chạy mà không cần thiết nếu và điều kiện
  • dựa trên một xác nhận toán học rằng sàn (thấp + cao) / 2 luôn nhỏ hơn cao trong đó thấp là giới hạn dưới và cao là giới hạn trên.

def binsearch(t, key, low = 0, high = len(t) - 1):
    # bisecting the range
    while low < high:
        mid = (low + high)//2
        if t[mid] < key:
            low = mid + 1
        else:
            high = mid
    # at this point 'low' should point at the place
    # where the value of 'key' is possibly stored.
    return low if t[low] == key else -1

Bạn có thể chia sẻ các trường hợp thử nghiệm?
cuộc sống

2

Giải pháp của Dave Abrahams là tốt. Mặc dù tôi đã làm nó tối giản:

def binary_search(L, x):
    i = bisect.bisect_left(L, x)
    if i == len(L) or L[i] != x:
        return -1
    return i

2

Mặc dù không có thuật toán tìm kiếm nhị phân rõ ràng trong Python, nhưng có một mô-đun bisect- được thiết kế để tìm điểm chèn cho một phần tử trong danh sách được sắp xếp bằng cách sử dụng tìm kiếm nhị phân. Điều này có thể bị "lừa" để thực hiện tìm kiếm nhị phân. Ưu điểm lớn nhất của điều này là cùng một ưu điểm mà hầu hết các mã thư viện đều có - đó là hiệu suất cao, được kiểm tra tốt và chỉ hoạt động (đặc biệt là tìm kiếm nhị phân có thể khá khó thực hiện thành công - đặc biệt là nếu các trường hợp cạnh không được xem xét cẩn thận).

Các loại cơ bản

Đối với các loại cơ bản như Chuỗi hoặc ints, nó khá dễ dàng - tất cả những gì bạn cần là bisectmô-đun và danh sách được sắp xếp:

>>> import bisect
>>> names = ['bender', 'fry', 'leela', 'nibbler', 'zoidberg']
>>> bisect.bisect_left(names, 'fry')
1
>>> keyword = 'fry'
>>> x = bisect.bisect_left(names, keyword)
>>> names[x] == keyword
True
>>> keyword = 'arnie'
>>> x = bisect.bisect_left(names, keyword)
>>> names[x] == keyword
False

Bạn cũng có thể sử dụng điều này để tìm các bản sao:

...
>>> names = ['bender', 'fry', 'fry', 'fry', 'leela', 'nibbler', 'zoidberg']
>>> keyword = 'fry'
>>> leftIndex = bisect.bisect_left(names, keyword)
>>> rightIndex = bisect.bisect_right(names, keyword)
>>> names[leftIndex:rightIndex]
['fry', 'fry', 'fry']

Rõ ràng bạn chỉ có thể trả về chỉ mục chứ không phải giá trị tại chỉ mục đó nếu muốn.

Các đối tượng

Đối với các loại hoặc đối tượng tùy chỉnh, mọi thứ phức tạp hơn một chút: bạn phải đảm bảo thực hiện các phương pháp so sánh phong phú để có được phép chia đôi để so sánh chính xác.

>>> import bisect
>>> class Tag(object):  # a simple wrapper around strings
...     def __init__(self, tag):
...         self.tag = tag
...     def __lt__(self, other):
...         return self.tag < other.tag
...     def __gt__(self, other):
...         return self.tag > other.tag
...
>>> tags = [Tag('bender'), Tag('fry'), Tag('leela'), Tag('nibbler'), Tag('zoidbe
rg')]
>>> key = Tag('fry')
>>> leftIndex = bisect.bisect_left(tags, key)
>>> rightIndex = bisect.bisect_right(tags, key)
>>> print([tag.tag for tag in tags[leftIndex:rightIndex]])
['fry']

Điều này sẽ hoạt động trong ít nhất Python 2.7 -> 3.3


1

Sử dụng một lệnh không muốn tăng gấp đôi mức sử dụng bộ nhớ của bạn trừ khi các đối tượng bạn lưu trữ thực sự rất nhỏ, vì các giá trị chỉ là con trỏ đến các đối tượng thực tế:

>>> a = 'foo'
>>> b = [a]
>>> c = [a]
>>> b[0] is c[0]
True

Trong ví dụ đó, 'foo' chỉ được lưu trữ một lần. Điều đó có làm nên sự khác biệt cho bạn không? Và chính xác có bao nhiêu mặt hàng chúng ta đang nói về?


Đó là về số lượng và rất nhiều trong số chúng :) Tôi muốn sử dụng một mảng lớn gần bằng bộ nhớ máy tính. Tôi biết cơ sở của vấn đề của tôi có thể sai, nhưng tôi tò mò về việc thiếu phương pháp tìm kiếm nhị phân.
rslite

1
Bạn không thể có một đối tượng chính đủ nhỏ để đủ điều kiện là "thực sự nhỏ bé" ở đây. Một đối tượng sẽ có chi phí tối thiểu là 3 từ (loại, tổng số, tải trọng), trong khi một danh sách thêm 1 từ, một bộ thêm 1 từ và một dict thêm 2 từ. Tất cả ba (danh sách / bộ / dict) không gian preallocate trong một số thời trang là một số nhân khác, nhưng vẫn không đủ để quan trọng.
Rhamphoryncus

1

Mã này hoạt động với danh sách số nguyên theo cách đệ quy. Tìm kịch bản trường hợp đơn giản nhất, đó là: chiều dài danh sách nhỏ hơn 2. Có nghĩa là câu trả lời đã có và một bài kiểm tra được thực hiện để kiểm tra câu trả lời đúng. Nếu không, giá trị trung bình được đặt và được kiểm tra là chính xác, nếu không chia đôi được thực hiện bằng cách gọi lại hàm, nhưng đặt giá trị trung bình là giới hạn trên hoặc dưới, bằng cách dịch chuyển sang trái hoặc phải

def binary_search (intList, intValue, lowValue, highValue):
    if (highValue - lowValue) <2:
        return intList [lowValue] == intValue hoặc intList [highValue] == intValue
    middleValue = lowValue + ((highValue - lowValue) / 2)
    if intList [middleValue] == intValue:
        trả lại đúng
    if intList [middleValue]> intValue:
        return binary_search (intList, intValue, lowValue, middleValue - 1)
   trả về binary_search (intList, intValue, middleValue + 1, highValue)

1

Kiểm tra các ví dụ trên Wikipedia http://en.wikipedia.org/wiki/Binary_search_alerskym

def binary_search(a, key, imin=0, imax=None):
    if imax is None:
        # if max amount not set, get the total
        imax = len(a) - 1

    while imin <= imax:
        # calculate the midpoint
        mid = (imin + imax)//2
        midval = a[mid]

        # determine which subarray to search
        if midval < key:
            # change min index to search upper subarray
            imin = mid + 1
        elif midval > key:
            # change max index to search lower subarray
            imax = mid - 1
        else:
            # return index number 
            return mid
    raise ValueError

0
'''
Only used if set your position as global
'''
position #set global 

def bst(array,taget): # just pass the array and target
        global position
        low = 0
        high = len(array)
    while low <= high:
        mid = (lo+hi)//2
        if a[mid] == target:
            position = mid
            return -1
        elif a[mid] < target: 
            high = mid+1
        else:
            low = mid-1
    return -1

Tôi đoán điều này là tốt hơn và hiệu quả. làm ơn sửa cho tôi :). Cảm ơn bạn


0
  • s là một danh sách.
  • binary(s, 0, len(s) - 1, find) là cuộc gọi ban đầu.
  • Hàm trả về một chỉ mục của mục được truy vấn. Nếu không có mục đó nó trả lại -1.

    def binary(s,p,q,find):
        if find==s[(p+q)/2]:
            return (p+q)/2
        elif p==q-1 or p==q:
            if find==s[q]:
                return q
            else:
                return -1
        elif find < s[(p+q)/2]:
            return binary(s,p,(p+q)/2,find)
        elif find > s[(p+q)/2]:
            return binary(s,(p+q)/2+1,q,find)

0
def binary_search_length_of_a_list(single_method_list):
    index = 0
    first = 0
    last = 1

    while True:
        mid = ((first + last) // 2)
        if not single_method_list.get(index):
            break
        index = mid + 1
        first = index
        last = index + 1
    return mid

0

Tìm kiếm nhị phân :

// List - values inside list
// searchItem - Item to search
// size - Size of list
// upperBound - higher index of list
// lowerBound - lower index of list
def binarySearch(list, searchItem, size, upperBound, lowerBound):
        print(list)
        print(upperBound)
        print(lowerBound)
        mid = ((upperBound + lowerBound)) // 2
        print(mid)
        if int(list[int(mid)]) == value:
               return "value exist"
        elif int(list[int(mid)]) < value:
             return searchItem(list, value, size, upperBound, mid + 1)
        elif int(list[int(mid)]) > value:
               return searchItem(list, value, size, mid - 1, lowerBound)

// Để gọi hàm trên, sử dụng:

list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
searchItem = 1        
print(searchItem(list[0], item, len(list[0]) -1, len(list[0]) - 1, 0))

0

Tôi cần tìm kiếm nhị phân trong python và generic cho các mô hình Django. Trong các mô hình Django, một mô hình có thể có khóa ngoại đối với mô hình khác và tôi muốn thực hiện một số tìm kiếm trên các đối tượng mô hình được truy xuất. Tôi đã viết chức năng sau đây bạn có thể sử dụng này.

def binary_search(values, key, lo=0, hi=None, length=None, cmp=None):
    """
    This is a binary search function which search for given key in values.
    This is very generic since values and key can be of different type.
    If they are of different type then caller must specify `cmp` function to
    perform a comparison between key and values' item.
    :param values:  List of items in which key has to be search
    :param key: search key
    :param lo: start index to begin search
    :param hi: end index where search will be performed
    :param length: length of values
    :param cmp: a comparator function which can be used to compare key and values
    :return: -1 if key is not found else index
    """
    assert type(values[0]) == type(key) or cmp, "can't be compared"
    assert not (hi and length), "`hi`, `length` both can't be specified at the same time"

    lo = lo
    if not lo:
        lo = 0
    if hi:
        hi = hi
    elif length:
        hi = length - 1
    else:
        hi = len(values) - 1

    while lo <= hi:
        mid = lo + (hi - lo) // 2
        if not cmp:
            if values[mid] == key:
                return mid
            if values[mid] < key:
                lo = mid + 1
            else:
                hi = mid - 1
        else:
            val = cmp(values[mid], key)
            # 0 -> a == b
            # > 0 -> a > b
            # < 0 -> a < b
            if val == 0:
                return mid
            if val < 0:
                lo = mid + 1
            else:
                hi = mid - 1
    return -1

0

Nhiều giải pháp tốt ở trên nhưng tôi chưa thấy một cách đơn giản (KISS giữ cho nó đơn giản (vì tôi) sử dụng hàm bisect được xây dựng / chung chung để thực hiện tìm kiếm nhị phân. Với một chút mã xung quanh hàm bisect, Tôi nghĩ rằng tôi có một ví dụ bên dưới, nơi tôi đã kiểm tra tất cả các trường hợp cho một chuỗi tên nhỏ. Một số giải pháp trên ám chỉ / nói điều này, nhưng hy vọng mã đơn giản dưới đây sẽ giúp bất kỳ ai nhầm lẫn như tôi.

Python bisect được sử dụng để chỉ ra nơi chèn một giá trị / mục tìm kiếm mới vào danh sách được sắp xếp. Đoạn mã dưới đây sử dụng bisect_left sẽ trả về chỉ mục của lần truy cập nếu tìm thấy mục tìm kiếm trong danh sách / mảng (Lưu ý bisect và bisect_right sẽ trả về chỉ mục của phần tử sau lần nhấn hoặc khớp làm điểm chèn) Nếu không tìm thấy , bisect_left sẽ trả về một chỉ mục cho mục tiếp theo trong danh sách được sắp xếp sẽ không == giá trị tìm kiếm. Một trường hợp khác là mục tìm kiếm sẽ ở cuối danh sách nơi chỉ mục được trả về sẽ nằm ngoài phần cuối của danh sách / mảng và trong đoạn mã bên dưới lối ra sớm của Python có xử lý logic "và". (điều kiện đầu tiên Sai Python không kiểm tra các điều kiện tiếp theo)

#Code
from bisect import bisect_left
names=["Adam","Donny","Jalan","Zach","Zayed"]
search=""
lenNames = len(names)
while search !="none":
    search =input("Enter name to search for or 'none' to terminate program:")
    if search == "none":
        break
    i = bisect_left(names,search)
    print(i) # show index returned by Python bisect_left
    if i < (lenNames) and names[i] == search:
        print(names[i],"found") #return True - if function
    else:
        print(search,"not found") #return False – if function
##Exhaustive test cases:
##Enter name to search for or 'none' to terminate program:Zayed
##4
##Zayed found
##Enter name to search for or 'none' to terminate program:Zach
##3
##Zach found
##Enter name to search for or 'none' to terminate program:Jalan
##2
##Jalan found
##Enter name to search for or 'none' to terminate program:Donny
##1
##Donny found
##Enter name to search for or 'none' to terminate program:Adam
##0
##Adam found
##Enter name to search for or 'none' to terminate program:Abie
##0
##Abie not found
##Enter name to search for or 'none' to terminate program:Carla
##1
##Carla not found
##Enter name to search for or 'none' to terminate program:Ed
##2
##Ed not found
##Enter name to search for or 'none' to terminate program:Roger
##3
##Roger not found
##Enter name to search for or 'none' to terminate program:Zap
##4
##Zap not found
##Enter name to search for or 'none' to terminate program:Zyss
##5
##Zyss not found
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.