哪种搜索方法更快?

时间:2014-01-06 22:46:32

标签: python python-3.3

我正在尝试演示不同的搜索方式,所以我尝试了一种强力迭代方式,第二种方法是将列表分成两半并从正面和背面进行检查。

哪个更快?或者我的代码是不是很糟糕?

我是Python的新手,所以只是掌握。

import itertools
import math

a = ["Rhys", "Jayne", "Brett", "Tool","Dave", "Paul"]

#Counts the length of the list
Length = 0
for i in a:
    Length = Length + 1
    print(Length)
#Brute force, iterative
counter = 0
print("Brute Force Search")
for i in a:
        if i != "Paul" :
            counter = counter +1
            print(counter)
            print("No")
        else:
            print("Yes")
            print (counter)

counter = 0 ## reset counter

#Binary Chop Attempt
print(" Binary Search")
i = 0
j = Length-1

while i <= math.ceil(Length/2):
    i = i+1
    while  j > math.ceil(Length/2):

        if a[i] != "Paul" or a[j]!= "Paul":
            print(j)
            print("No")
        else:
            print("Yes")

            break
        j = j-1
#Binary Chop Attempt2
print(" Binary Search 2")
i = 0
j = Length-1
found = False
while i <= math.ceil(Length/2) or j > math.ceil(Length/2): 

    if found == True:
        break

    if a[i] != "Paul" or a[j]!= "Paul":

            print("Not in position "  + str(i))
    else:
            print("Found in position" + str(i))
            found = True
    if  a[j]!= "Paul":

            print("Not in position " + str(j))
    else:
            print("Found In position " + str(j))
            found = True


    j = j-1
    i = i+1

由于

4 个答案:

答案 0 :(得分:4)

a = ["Rhys", "Jayne", "Brett", "Tool","Dave", "Paul"]
print a.index('Paul')

这将比你可以提出的任何C算法转录到python更快,这可以达到相当大的列表大小。

所以第一个问题是;还不够好吗?

如果不是,那么下一个寻找的pythonic地方将是标准库(注意二进制搜索需要排序输入!):

a = sorted( ["Rhys", "Jayne", "Brett", "Tool","Dave", "Paul"])
from bisect import bisect_left as bisect
print bisect(a, 'Paul')

或者可能更需要set()或dict();但这一切都取决于你究竟想要达到的目的。

答案 1 :(得分:2)

嗯,你的代码并没有那么糟糕。一般概念都可以。你称之为“暴力”的东西实际上被称为“表扫描”,至少在数据库的上下文中。有时这是你唯一的方式。

你的第二个代码与第一个代码没有什么不同。因为在Python中“get”在列表上是O(1)然后无论你如何“跳跃”,你最终会得到几乎相同的结果(假设你对列表一无所知,特别是它的顺序)。你可以做测试并测量它(我太懒了)。

然而,可以做一些改进:

1)保持列表排序。这样你可以应用“除法”算法,即你从中间开始,如果值小于你给定的那个,你进入上半场的中间。否则你会进入下半场中段。依此类推......这将允许您在O(log(n))

中搜索

2)使用其他结构然后列出。某种B树。这将允许您在O(log(n))中搜索。

3)最后使用字典。这是一个非常好的结构,允许你在O(1)中搜索一个键(不可能更快,宝贝)。如果你真的需要维护数组的顺序,可以像这样使用字典:键是元素,值是按顺序排列的位置。

4)使用索引。这几乎与上述其中一点相同,除了你使用不同的结构而不是而不是,而除了。当你有一个复杂对象列表并希望能够根据多个属性进行有效搜索时,维护起来有点困难,但很好。

答案 2 :(得分:0)

二进制搜索仅在列表被排序时才有意义。如果它是无序的,检查第一个和最后一个然后第二个和第二个到第二个与检查第一个,第二个,第三个和第四个没有什么不同。最终,你必须检查所有。订单无关紧要。

如果希望二进制搜索有效,则必须对列表进行排序,然后二进制搜索必须根据事物的排序事实进行搜索。这就是二进制的工作原理;它会删除部分。它是旧的“高或低”游戏。你猜50,他们说高。现在你知道它不能超过50+。所以现在你只需要搜索1-50。现在你猜25。他们说低。所以现在你知道它不能是1-25。所以现在你选择25和50的中间位置。

答案 3 :(得分:0)

您的“蛮力”搜索通常称为“线性”搜索。在Python中,那只是

# Linear search
"Paul" in a

您的“二进制文件”通常需要“二进制”搜索,它取决于要排序的输入列表。您可以使用sorted功能对列表进行排序,或只使用set

# Binary search
"Paul" in set(a)

二进制搜索是否比线性搜索更快取决于一些事情(例如,对列表进行排序有多贵?),它肯定并不总是更快。如果有疑问,请使用timeit模块对代码进行某些代表性数据的基准测试。