简体   繁体   English

比较两个包含数字的 python 字符串

[英]compare two python strings that contain numbers

UPDATE: I should have specified this sooner, but not all of the names are simply floats.更新:我应该早点指定这一点,但并非所有名称都只是浮点数。 For example, some of them are "prefixed" with "YT".例如,其中一些“前缀”为“YT”。 So for example" YT1.1. so, you have the same problem YT1.9 < YT1.11 should be true. I'm really surprised that the string comparison fails....所以例如“YT1.1。所以,你有同样的问题 YT1.9 < YT1.11 应该是真的。我真的很惊讶字符串比较失败......

hello, this should be a pretty simple question but I can't seem to find the answer.你好,这应该是一个非常简单的问题,但我似乎找不到答案。 I'd like to sort a bunch of XL worksheets by name.我想按名称对一堆 XL 工作表进行排序。 Each of the names are numbers but in the same way that textbook "sections" are numbered, meaning section 4.11 comes after 4.10 which both come after 4.9 and 4.1.每个名称都是数字,但与教科书“部分”的编号方式相同,这意味着第 4.11 节在 4.10 之后,这两者都在 4.9 和 4.1 之后。 I thought simply comparing these numbers as string would do but I get the following:我认为简单地将这些数字作为字符串进行比较就可以了,但我得到以下信息:

>>> s1 = '4.11'
>>> s2 = '4.2'
>>> s1> s2
False
>>> n1 = 4.11
>>> n2 = 4.2
>>> n1 > n2
False

how can I compare these two values such that 4.11 is greater than 4.2?如何比较这两个值,使 4.11 大于 4.2?

Convert the names to tuples of integers and compare the tuples:将名称转换为整数元组并比较这些元组:

def splittedname(s):
    return tuple(int(x) for x in s.split('.'))

splittedname(s1) > splittedname(s2)

Update : Since your names apparently can contain other characters than digits, you'll need to check for ValueError and leave any values that can't be converted to ints unchanged:更新:由于您的姓名显然可以包含数字以外的其他字符,您需要检查ValueError并保留任何无法转换为整数的值不变:

import re

def tryint(x):
    try:
        return int(x)
    except ValueError:
        return x

def splittedname(s):
    return tuple(tryint(x) for x in re.split('([0-9]+)', s))

To sort a list of names, use splittedname as a key function to sorted :要对名称列表进行排序,请使用splittedname作为sorted的键函数:

>>> names = ['YT4.11', '4.3', 'YT4.2', '4.10', 'PT2.19', 'PT2.9']
>>> sorted(names, key=splittedname)
['4.3', '4.10', 'PT2.9', 'PT2.19', 'YT4.2', 'YT4.11']

This is not a built-in method, but it ought to work:这不是内置方法,但它应该可以工作:

>>> def lt(num1, num2):
...     for a, b in zip(num1.split('.'), num2.split('.')):
...         if int(a) < int(b):
...             return True
...         if int(a) > int(b):
...             return False
...     return False
... 
... lt('4.2', '4.11')
0: True

That can be cleaned up, but it gives you the gist.这可以清理,但它给你的要点。

What you're looking for is called "natural sorting".您正在寻找的称为“自然排序”。 That is opposed to "lexicographical sorting".这与“词典排序”相反。 There are several recipes out there that do this, since the exact output of what you want is implementation specific.有几种方法可以做到这一点,因为您想要的确切输出是特定于实现的。 A quick google search yields this (note* this is not my code, nor have I tested it):快速谷歌搜索产生这个(注意*这不是我的代码,我也没有测试过):

import re

def tryint(s):
    try:
        return int(s)
    except:
        return s

def alphanum_key(s):
    """ Turn a string into a list of string and number chunks.
        "z23a" -> ["z", 23, "a"]
    """
    return [ tryint(c) for c in re.split('([0-9]+)', s) ]

def sort_nicely(l):
    """ Sort the given list in the way that humans expect.
    """
    l.sort(key=alphanum_key)

http://nedbatchelder.com/blog/200712.html#e20071211T054956 http://nedbatchelder.com/blog/200712.html#e20071211T054956

use s1.split(".") to create a list of the items before and after the decimal then sort the list of lists, example:使用s1.split(".")创建小数点前后项目的列表,然后对列表列表进行排序,例如:

import random
sheets = list([str(x), str(y)] for x in xrange(1, 5) for y in xrange(0,99))
print sheets
#sheets in order
random.shuffle(sheets)
print sheets
#sheets out of order
sheets.sort()
print sheets
#sheets back in order

So, you implementation might be:所以,你的实现可能是:

#assume input sheets is a list of the worksheet names
sheets = list(x.split(".") for x in input_sheets)
sheets.sort()

If you know they are real numbers [*] , simply:如果您知道它们是实数 [*] ,只需:

>>> float(s1) > float(s2)
True

[*] Otherwise, be ready to handle a raised ValueError . [*] 否则,准备好处理引发的ValueError

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM