我正在尝试在django中实现一个搜索功能,它根据字符串过滤记录列表,与django admin list filtering
但是,我们不会根据从搜索表单中获取的查询字符串来过滤结果from the database
,而是我们需要filter from the list
我已经
views.py
def filter_contacts(request):
contacts = ['None <steve.one@gmail.com>', 'None <ronold@gmail.com>',
'None <jacksparrow@gmail.com>', 'None <dude@gmail.com>' ...... up to more than 1000]
if request.GET:
if request.GET.has_key('q'):
contacts = **filter the contacts from the above list that contains query string "q" and create a new list**
else:
contacts = contacts
return render_to_response('social_feeds/gmail_contacts.html', {'contacts':contacts})
search_form类似
<form class="form-search" action="{% url 'contacts' %}" method="get">
<div class="input-append">
<input type="text" class="span2 search-query" name="q" value="" id="searchbar">
<button type="submit" class="btn btn-primary" value="Search">Search</button>
</div>
</form>
当然,我们可以通过query string
过滤列表中的looping
并搜索列表中每个字符串中的字符串,如果它已创建新列表,
但是,自从/假设我们有超过1000个字符串(可能是上面的电子邮件),该过程应该very/ultimately
快,所以寻找基于{functionality/process/method
非常快速过滤列表的query paramerter
{1}}喜欢假设
如果我们使用steve
搜索表单,则应将包含strings/emails
的所有steve
过滤到新列表,这就是我要找的内容
任何人都可以告诉我如何快速实现搜索功能吗?
答案 0 :(得分:0)
最快的方法是将电子邮件放在数据库中,然后使用查询来获取它们。像这样:
models.py
class Contact(models.model):
email = models.EmailField()
然后在views.py中:
if request.GET.has_key('q'):
query = request.GET['q']
contacts = Contact.objects.all().filter(email__contains=query)
如果失败了,你想要使用pythonic方式。可能有更快的方法而不是简单的循环,但是再次,循环并不像你想象的那么慢。我拿了一个60k的电子邮件列表(this one!),并在所谓的“慢速方法”中循环使用它,如下所示:
f = open('maillist.txt', 'rb')
lines = f.readlines()
res = []
for l in lines:
if 'steve' in l:
res.append(l)
时间表明它需要大约0.008秒才能完成。
为了表明“简单”方法的速度有多快,我想出了不同的方法来实现相同的结果:
timing = {}
res = []
import time
# normal iteration
start = time.time()
for l in lines:
if 'steve' in l:
res.append(l)
end = time.time()
timing['iteration'] = end-start
length = len(res)
res = []
# list comprehension
start = time.time()
[res.append(l) for l in lines if 'steve' in l]
end = time.time()
timing['list comprehension'] = end-start
assert(len(res) == length)
#
def search(s):
res =[]
if 'steve' in s:
res.append(s)
return res
# built in 'filter' method
start = time.time()
res = filter(search, lines)
end = time.time()
timing['filter'] = end-start
assert(len(res) == length)
#using itertools
import itertools
start = time.time()
res = itertools.ifilter(search, lines)
end = time.time()
timing['ifilter'] = end-start
for key, value in timing.iteritems():
print key, value, 'seconds'
行是上述60k电子邮件列表的列表,结果如下:
iteration 0.00799989700317 seconds
list comprehension 0.00699996948242 seconds
filter 0.0130000114441 seconds
ifilter 0.0 seconds
如您所见,最快的方法是使用列表理解。这是为了计算电子邮件中是否有'steve',但是如果你做了一些更复杂的事情,比如电子邮件中的'steve'或电子邮件中的'smith'比结果稍有变化:
iteration 0.0139999389648 seconds
list comprehension 0.010999917984 seconds
filter 0.0169999599457 seconds
ifilter 0.0 seconds
仍然,列表理解是胜利者。您可能想知道为什么ifilter需要0次,但这很简单 - ifilter创建了一个生成器。动态加载结果可以证明您的需求是有效的。
无论如何,正如您可以清楚地看到的那样,所有这些版本之间的差异都是以毫秒为单位。我无法想象你需要比这更快的东西,但你应该测试和计时不同的方法,如果你发现你仍然需要更多的东西,只需去pypi并寻找一个允许快速过滤的包。