解析了IANA子标签(请参阅Cascaded string split, pythonic way)并列出了8600个标签:
tags= ['aa',
'ab',
'ae',
'af',
'ak',
'am',
'an',
'ar',
# ...
我想查看示例mytag="ro"
是否在列表中:
最快的方法是什么:
第一个解决方案:
if mytag in tags:
print "found"
第二个解决方案:
if mytag in Set(tags):
print "found"
第三个解决方案:在一个大字符串中转换列表,如:'|aa|ab|ae|af|ak|am|an|ar|...'
,然后查看字符串是否在另一个字符串中:
tags = '|aa|ab|ae|af|ak|am|an|ar|...'
if mytag in tags:
print "found"
还有其他方法吗?哪个是最快的,这是否已经测量过,如果不是我怎么能自我测量(我从列表中取一个随机元素或者我应该拿最后一个然后测试它,有人可以为'天文台'提供python代码)吗?
答案 0 :(得分:6)
由于我无法访问原始字符串,因此任何测试都会有偏差。但是,你问了一个天文台?检查timeit
模块,该模块旨在为一些代码段提供时间。
请注意,如果您使用IPython
,%timeit
是一个神奇的函数,可以轻松地执行函数,如下所示。
一些评论
Set
替换为set
... set
和长字符串tags
列表中取一个随机元素是真正的方法。作为在IPython中使用%timeit
的一个例子:
tags = ['aa','ab','ae','af','ak','an','ar']
tags_set = set(tags)
tags_str = "|".join(tags)
%timeit 'ro' in tags
1000000 loops, best of 3: 223 ns per loop
%timeit 'ro' in tags_set
1000000 loops, best of 3: 73.5 ns per loop
%timeit 'ro' in tags_str
1000000 loops, best of 3: 98.1 ns per loop
答案 1 :(得分:2)
与时间或性能无关,但您可能不会因为以不同方式构建数据而更加担心此类事情。
查看您之前的帖子,您接受的答案包含一个函数iana_parse
,它产生了一个词典。所以,如果你知道你在寻找解析前的时间,那么你可以这样做:
looking_for = {'ro', 'xx', 'yy', 'zz'}
for res in iana_parse(data): # from previous post
if res['Subtag'] in looking_for:
print res['Subtag'], 'was found'
否则(或与之结合使用),您可以从该函数构建一个dict并使用:
subtag_lookup = {rec['Subtag']:rec for rec in iana_parse(data)}
ro = subtag_lookup['ro']
print ro['Description']
在某些时候,如果您只想要一个子标签列表,请使用:
subtags = list(subtag_lookup)
答案 2 :(得分:1)
你可以自己检查一下。只需使用timeit
模块..
timeit.Timer()可能对您有用..
或者,您也可以使用time模块: -
import time
ct = time.clock()
if mytag in tags:
print "found"
print "diff: ", time.clock() - ct
答案 3 :(得分:1)
我更喜欢#1。它应该从您提供的选项中为您提供最佳性能,因为您在比较之前没有对列表进行额外处理。
至于如何测试表现...... timeit就是你想要的。
import timeit
s1 = """
tags= ['aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar']
mytag = 'ro'
if mytag in tags:
print 'found'
"""
s2 = """
tags= ['aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar']
mytag = 'ro'
if mytag in set(tags):
print 'found'
"""
s3 = """
tags= ['aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar']
mytag = 'ro'
if mytag in '|'.join(tags):
print 'found'
"""
print(timeit.Timer(s1, 'gc.enable()').timeit())
print(timeit.Timer(s2, 'gc.enable()').timeit())
print(timeit.Timer(s3, 'gc.enable()').timeit())
>>>
0.261634511713
0.476344575019
0.282574283666
答案 4 :(得分:1)
我自己使用此代码完成了测试,您可以在IPython控制台中使用%cpaste
并粘贴下面的代码。
#Get IANA language defs
import urllib
import pprint
import timeit
import IPython
import random
f = urllib.urlopen("http://www.iana.org/assignments/language-subtag-registry")
#lan.split("%%") .split("\n").split(":")
lan=f.read()
def iana_parse(data):
for record in data.split("%%\n"):
# skip empty records at file endings:
if not record.strip():
continue
rec_data = {}
for line in record.split("\n"):
# key, value = line.split(":") doesn't work
key, value = line.partition(':')[::2]
# key, _, value = line.partition(':')
rec_data[key.strip()] = value.strip()
yield rec_data
tags =[]
for k in iana_parse(lan):
# print k
if "Subtag" in k: tags.append(k["Subtag"])
#maybe store it in a shelve http://docs.python.org/library/shelve.html
tags_set = set(tags)
tags_str = "|".join(tags)
print "Search 'ro'"
print "List:"
%timeit 'ro' in tags
print "Set:"
%timeit 'ro' in tags_set
print "String:"
%timeit 'ro' in tags_str
random_tag = tags[random.randint(0,len(tags)-1)]
print "Search random"
print "List:"
%timeit random_tag in tags
print "Set:"
%timeit random_tag in tags_set
print "String:"
%timeit random_tag in tags_str
结果是:
Search 'ro'
List: 1000000 loops, best of 3: 1.61 us per loop
Set: 10000000 loops, best of 3: 45.2 ns per loop
String: 1000000 loops, best of 3: 239 ns per loop
Search random
List:10000 loops, best of 3: 36.2 us per loop
Set:10000000 loops, best of 3: 50.9 ns per loop
String:100000 loops, best of 3: 4.88 us per loop
所以顺序是:
答案 5 :(得分:1)
选项#1应该是一次性使用最快的,因为它甚至不需要遍历整个列表(构建一个需要通过整个列表的集合),而#2将是最快的所有下一次运行(如果你只构建一次set()),因为它将在很小的恒定时间内工作。