Python 为什么Sort(s1)=Sort(s2)比Counter(s1)=Counter(s2)更适合使用
这被认为是检查两个字符串是否相互排列的有效方法吗?使用两本词典有什么区别?计数器是否针对python进行了更优化 我想我应该澄清一下,我发表这篇评论的原因是:提到使用sort(s1)=sort(s2)检查两个字符串是否相同更有效。因为这是o(nlog(n)),所以您会假设计数器的运行时间更好。它是o(n),所以理论上是有效的。Python 为什么Sort(s1)=Sort(s2)比Counter(s1)=Counter(s2)更适合使用,python,string,Python,String,这被认为是检查两个字符串是否相互排列的有效方法吗?使用两本词典有什么区别?计数器是否针对python进行了更优化 我想我应该澄清一下,我发表这篇评论的原因是:提到使用sort(s1)=sort(s2)检查两个字符串是否相同更有效。因为这是o(nlog(n)),所以您会假设计数器的运行时间更好。它是o(n),所以理论上是有效的。计数器是一个字典子类,因此唯一的区别是您必须用Python构建字典,而不是让计数器类(声称是“高性能”的,所以我假设是用C实现的)来做。两者都是相同的大O,但计数器将更快
计数器
是一个字典子类,因此唯一的区别是您必须用Python构建字典,而不是让计数器
类(声称是“高性能”的,所以我假设是用C实现的)来做。两者都是相同的大O,但计数器将更快
这是一个不同的大O,但对两个字符串进行排序实际上比我的系统中的短字符串的计数器快四倍左右。它是O(n),因此理论上是有效的。计数器
是一个字典子类,因此唯一的区别是您必须用Python构建字典,而不是让计数器
类(声称是“高性能”的,所以我假设是用C实现的)来做。两者都是相同的大O,但计数器将更快
这是一个不同的big-O,但在我的系统中,对两个字符串进行排序实际上比对短字符串使用计数器快四倍左右。在你提到的另一个问题中,理论上说,在几乎所有情况下,使用排序
都比使用计数器
快,但他明智地指出,如果你真的在意,你应该衡量:“实际上,它可能总是比collections.Counter()
更快(尽管渐进O(n)
时间比O(n*log(n))
更适合。sort()
)。如果它很重要,就衡量它。”
这种测量结果如下所示。要点:
- 对于大约
10^6
的列表大小,sort
更快
- 随着列表大小的增加,这种优势逐渐减弱
- 这些实验使用具有许多离散值的列表。如果列表中重复值的百分比较高,则基准可能会有所不同
- 这些测量结果表明,创建
计数器的开销通常大于就地排序数据的成本。考虑这一点的一种方法是查看排序方法中日志(n)
部分的计数器创建开销。直到n
变得相当大,计数器
数据结构的算法优势才开始有足够的回报来证明这种开销
- 但请记住:对于较小的数据量,速度优势可能无关紧要——除非您在大容量下重复该操作。从这个角度来看,“算法正确”的方法(使用
计数器
)在大多数用例中从代码设计的角度来看可能更好——因为如果数据大,它会更快,如果数据小,它会足够快
守则:
import timeit, sys, random
from collections import Counter
def prep():
random.shuffle(xs)
random.shuffle(ys)
def use_counter():
prep()
return Counter(xs) == Counter(ys)
def use_sort():
prep()
xs.sort()
ys.sort()
return xs == ys
experiments = [
(3, 10, 100000),
(3, 100, 10000),
(3, 1000, 1000),
(3, 10000, 100),
(3, 100000, 10),
(3, 1000000, 1),
(1, 10000000, 1),
]
for e in experiments:
repeat, list_size, timeit_n = e
xs = list(range(list_size))
ys = list(range(list_size))
r1 = timeit.repeat(use_counter, repeat = repeat, number = timeit_n)
r2 = timeit.repeat(use_sort, repeat = repeat, number = timeit_n)
print
print e
print 'total ', sum(r1), sum(r2)
print 'm1/m2 ', min(r1) / min(r2)
示例输出(比率>1表示计数器较慢):
在你提到的另一个问题中,他从理论上推断,在几乎所有情况下,使用排序
都比使用计数器
快,但他明智地指出,如果你真的在意,你应该衡量:“实际上,它可能总是比集合.Counter()
(尽管是渐进的O(n))
时间比O(n*log(n))
对于.sort()
)更好。如果重要,请测量它。”
这种测量结果如下所示。要点:
- 对于大约
10^6
的列表大小,sort
更快
- 随着列表大小的增加,这种优势逐渐减弱
- 这些实验使用具有许多离散值的列表。如果列表中重复值的百分比较高,则基准可能会有所不同
- 这些测量结果表明,创建
计数器的开销通常大于就地排序数据的成本。考虑这一点的一种方法是查看排序方法中日志(n)
部分的计数器创建开销。直到n
变得相当大,计数器
数据结构的算法优势才开始有足够的回报来证明这种开销
- 但请记住:对于较小的数据量,速度优势可能无关紧要——除非您在大容量下重复该操作。从这个角度来看,“算法正确”的方法(使用
计数器
)在大多数用例中从代码设计的角度来看可能更好——因为如果数据大,它会更快,如果数据小,它会足够快
守则:
import timeit, sys, random
from collections import Counter
def prep():
random.shuffle(xs)
random.shuffle(ys)
def use_counter():
prep()
return Counter(xs) == Counter(ys)
def use_sort():
prep()
xs.sort()
ys.sort()
return xs == ys
experiments = [
(3, 10, 100000),
(3, 100, 10000),
(3, 1000, 1000),
(3, 10000, 100),
(3, 100000, 10),
(3, 1000000, 1),
(1, 10000000, 1),
]
for e in experiments:
repeat, list_size, timeit_n = e
xs = list(range(list_size))
ys = list(range(list_size))
r1 = timeit.repeat(use_counter, repeat = repeat, number = timeit_n)
r2 = timeit.repeat(use_sort, repeat = repeat, number = timeit_n)
print
print e
print 'total ', sum(r1), sum(r2)
print 'm1/m2 ', min(r1) / min(r2)
示例输出(比率>1表示计数器较慢):
为什么不在几个string
示例中使用timeit
,自己检查一下呢?你问的是短字符串还是很长的字符串?不要忘记将每个字符串排序到字符列表中并比较结果列表的选项。我想这是我的问题。为什么检查两个字符串之间的排序比counter(s1)=counter(s2)更有效,正如我希望您在说=
时所指的那样。它会产生巨大的差异(和巨大的错误)。如果有人能回答这个问题,你为什么不在字符串的几个例子中使用timeit
,然后自己检查一下,这会很有帮助?你是在问关于s的事吗