Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么Sort(s1)=Sort(s2)比Counter(s1)=Counter(s2)更适合使用_Python_String - Fatal编程技术网

Python 为什么Sort(s1)=Sort(s2)比Counter(s1)=Counter(s2)更适合使用

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进行了更优化

我想我应该澄清一下,我发表这篇评论的原因是:提到使用sort(s1)=sort(s2)检查两个字符串是否相同更有效。因为这是o(nlog(n)),所以您会假设计数器的运行时间更好。

它是o(n),所以理论上是有效的。
计数器
是一个字典子类,因此唯一的区别是您必须用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的事吗