Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.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自然比较?_Python_Unix_Sorting - Fatal编程技术网

字符串之间的python自然比较?

字符串之间的python自然比较?,python,unix,sorting,Python,Unix,Sorting,Python是否有在两个字符串之间进行自然排序的快速函数?不必排序,只需要一个比较函数,它返回0、-1或1,这取决于哪个在自然顺序或相同顺序的前面 编辑:建议的函数是正确的,但速度太慢。如何在Python中快速实现这一点 注意这不是许多人建议的帖子的翻版——因为这些其他帖子没有解决效率问题。当前的解决方案是有效的,并且是正确的,但是对每一行都进行正则表达式调用,这非常昂贵。我想要一个高效的解决方案,可以用来进行数百万次的比较。是实现这一点的内置函数 >>> a = 'hello

Python是否有在两个字符串之间进行自然排序的快速函数?不必排序,只需要一个比较函数,它返回0、-1或1,这取决于哪个在自然顺序或相同顺序的前面

编辑:建议的函数是正确的,但速度太慢。如何在Python中快速实现这一点

注意这不是许多人建议的帖子的翻版——因为这些其他帖子没有解决效率问题。当前的解决方案是有效的,并且是正确的,但是对每一行都进行正则表达式调用,这非常昂贵。我想要一个高效的解决方案,可以用来进行数百万次的比较。

是实现这一点的内置函数

>>> a = 'hello'
>>> b = 'world'
>>> cmp(a, b)
-1

编辑:使用“自然排序”时,您是否像人类一样对数字进行排序?如果是这种情况,那么这是一个可能的配方。

根据对该问题的回答改编:

更新

使用ipython计时(使用示例输入):

In [1]: %timeit nat_cmp('foo10z', 'foo100z')
100000 loops, best of 3: 11.6 us per loop
更新2

说到表演。。。我不确定您是否理解与纯python代码相比,
re
lib实际上有多快。为了演示,我使用了关键函数(带有
re
)并用纯python重写了几次,并将它们的速度与使用
re.split
简单得多的方法进行了比较

import re
from itertools import groupby

def regex_key(key):
    """Traditional, regular-expression-based nat-sort key."""
    convert = lambda text: int(text) if text.isdigit() else text.lower()
    return [convert(c) for c in re.split('([0-9]+)', key)]

def fast_key(value):
    """Attempt #1 to go faster than 'slow' 're' library."""
    result = []
    for is_int, chunk in groupby(value.lower(), str.isdigit):
        if is_int:
            result.append(int(''.join(chunk)))
        else:
            result.append(tuple(chunk))
    return result

def faster_key(value):
    """Attempt #2.  'Low-level' python."""
    start_idx = 0
    is_num = None
    result = []
    for idx, c in enumerate(value.lower()):
        now_is_num = c.isdigit()
        if is_num is not None and now_is_num != is_num:
            buf = value[start_idx:idx]
            result.append(int(buf) if is_num else buf)
            start_idx = idx
            is_num = None
        is_num = now_is_num
    buf = value[start_idx:]
    result.append(int(buf) if is_num else buf)
    return result
接下来,我针对一个简单的基准测试运行这些测试:

from datetime import datetime

def benchmark(fn):
    print "Benching %s (run 1000 times)" % fn.__name__

    start = datetime.now()
    for x in xrange(1000):
        # run key function on something approx 100 chars long
        fn('asdf1234sdfg234jhd88123j2134 - 123d34123djfsk'*2)
    print "\t%s" % (datetime.now() - start)

benchmark(regex_key)
benchmark(fast_key)
benchmark(faster_key)
结果如下:

Benching regex_key (run 1000 times)
    0:00:00.025908
Benching fast_key (run 1000 times)
    0:00:00.065567
Benching faster_key (run 1000 times)
    0:00:00.042654

现在,我确信我可以做一些事情来加快我的key func实现,但除非我遗漏了一些重要的东西,否则很难像
re.split
代码(即使用纯python)那样快。这将允许您自然地对字符串列表进行排序:

import re

unsorted_list = ["a1", "a2", "a11", "b1", "b2", "b11"]

def natural_key(s):
    return [ int(c) if c.isdigit() else c for c in re.split(r'(\d+)', s) ]

sorted_list = sorted(unsorted_list, key = lambda x : natural_key(x))

print sorted_list

这将返回-1、0或1,具体取决于x>y

def natural_key(x, y):
     x = [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', x)]
     y = [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', y)]
     if x == y:
          return 0
     elif x > y:
          return 1
     else:
          return -1

这在Python2.X和3.X中起作用,定义“自然顺序”。它的可能重复不是重复,因为这些其他线程不能有效地解决这个问题。当前的解决方案对每一行都进行正则表达式调用,这是令人望而却步的expensive@user248237-(1)编辑应提高问题的清晰度,而不是改变其性质。你开始询问功能,然后变成了一个关于速度的问题。(2) 正则表达式的速度非常快[相对于它们所做的工作量而言]。(3) 像
cmp
这样的比较函数速度很快,因为它们在位级别进行比较。任何需要“人类逻辑”的东西都会慢得多。@user248237-不。如果这是您想要的行为,请查看我的编辑(我没有直接粘贴代码,因为ActiveState网站上有一长串有趣的观察结果)。您无法再将
int
str
进行比较。另外,
cmp
也被删除了。实际上这个函数非常慢——我不得不与它进行数百万次的比较。HTEE是一种加速它的方法吗?你能给我一个你比较的例子吗?和你认为慢的一个例子吗?@阿达姆瓦格纳:我正在比较50-100万个字符串的顺序。每个字符串的长度大约为100个字符,您看到的速度是多少?我对大约100个字符长的字符串进行了测试,平均运行时间为65us。我知道您正在处理大量的数据,但是如果您的性能要求非常高,也许您应该研究python以外的东西。这就是说,这应该(如果我计算正确的话)每秒产生超过10万次的比较。
import re

unsorted_list = ["a1", "a2", "a11", "b1", "b2", "b11"]

def natural_key(s):
    return [ int(c) if c.isdigit() else c for c in re.split(r'(\d+)', s) ]

sorted_list = sorted(unsorted_list, key = lambda x : natural_key(x))

print sorted_list
def natural_key(x, y):
     x = [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', x)]
     y = [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', y)]
     if x == y:
          return 0
     elif x > y:
          return 1
     else:
          return -1