Python - 带有字母数字的人类数字排序,但在 pyQt 和 __lt__ 运算符中
我有数据行并希望将它们呈现如下:
1
1a
1a2
2
3
9
9.9
10
10a
11
100
100ab
ab
aB
AB
由于我使用 pyQt 并且代码包含在 TreeWidgetItem 中,所以我试图解决的代码是:
def __lt__(self, otherItem):
column = self.treeWidget().sortColumn()
#return self.text(column).toLower() < otherItem.text(column).toLower()
orig = str(self.text(column).toLower()).rjust(20, "0")
other = str(otherItem.text(column).toLower()).rjust(20, "0")
return orig < other
I have data rows and wish to have them presented as follows:
1
1a
1a2
2
3
9
9.9
10
10a
11
100
100ab
ab
aB
AB
As I am using pyQt and code is contained within a TreeWidgetItem, the code I'm trying to solve is:
def __lt__(self, otherItem):
column = self.treeWidget().sortColumn()
#return self.text(column).toLower() < otherItem.text(column).toLower()
orig = str(self.text(column).toLower()).rjust(20, "0")
other = str(otherItem.text(column).toLower()).rjust(20, "0")
return orig < other
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这可能对你有帮助。编辑正则表达式以匹配您感兴趣的数字模式。我的会将任何包含
.
的数字字段视为浮点数。使用swapcase()
反转大小写,以便'A'
排序在'a'
之后。更新:精炼:
输出:
更新:(对评论的回应)如果您有一个类
Foo
并且想要实现__lt__ 使用
_ human_key
排序方案,只需返回_ human_key(k1)
的结果_ human_key(k2)
;因此,对于您的情况,您需要执行以下操作:
其他比较运算符(
__eq__
、__gt__
等)将以相同的方式实现。This may help you. Edit the regexp to match the digit patterns you're interested in. Mine will treat any digit fields containing
.
as floats. Usesswapcase()
to invert your case so that'A'
sorts after'a'
.Updated: Refined:
Output:
Update: (response to comment) If you have a class
Foo
and want to implement__lt__
using the_human_key
sorting scheme, just return the result of_human_key(k1) < _human_key(k2)
;So for your case, you'd do something like this:
The other comparison operators (
__eq__
,__gt__
, etc) would be implemented in the same way.使用 samplebias 的
swapcase
想法,以及 Ned Batchelder 的 人类排序代码,你可以这样做:你可以在
__lt__
中应用human_keys
,如下所示:Using samplebias's
swapcase
idea, and Ned Batchelder's human-sort code, you might do it this way:You could apply
human_keys
in__lt__
like this:我不明白你的排序算法,所以我无法告诉你如何实现它。但有一个通用的技巧,那就是使用Python内置的
sort
函数中的key
参数。换句话说,您想要对数据进行一些转换,Python 会按正确的顺序进行排序,然后将该转换编写为 Python 函数foo
并调用sort(data,键=foo)
。示例:如果您有一个字符串列表
"-"
,请说["1-1","1-2 ","3-1"]
并且您想按第二个数字排序,然后按第一个数字排序,请注意,如果数据采用[(1,1), (2,1), (1,3)]
即反转元组列表。因此,您可以编写一个函数,然后使用
sort(l, key=key)
对列表进行排序。I don't understand your sort algorithm, so I can't tell you how to implement it. But there is a general technique, which is to use the
key
parameter in Python's builtinsort
function. In other words, you want to come up with some transformation of your data which Python would sort in the correct order, and then write that transformation as a Python functionfoo
and callsort(data, key=foo)
.Example: if you had a list of strings
"<integer>-<integer>"
, say["1-1","1-2","3-1"]
and you wanted to sort by the second number and then the first, notice that Python would sort the data correctly if it were in the form[(1,1), (2,1), (1,3)]
i.e. a list of reversed tuples. So you would write a functionand then sort the list with
sort(l, key=key)
.这是一个函数,给定一个混合有字母和数字部分的字符串,返回一个以“自然”方式排序的元组。
它使用的基本方法是,当它看到一个数字时,它会收集额外的字符并不断尝试将结果转换为数字,直到它不能再转换为止(即它收到异常)。默认情况下,它会尝试将连续字符转换为整数,但您可以传入
convert=float
以使其接受小数点。 (不幸的是,它不接受科学记数法,因为要得到像“1e3”这样的东西,它首先会尝试解析无效的“1e”。这与+或-号一起,可能是特殊情况,但它并不看起来这对于您的用例来说不是必需的。)该函数返回一个包含字符串和数字的元组,按照它们在字符串中找到的顺序排列,并将数字解析为指定的数字类型。例如:
该元组可以用作对字符串列表进行排序的键:
或者您可以使用它来实现比较功能:
在对象的
__init__() 中生成自然键会更好(更快)
方法,将其存储在实例中,然后编写比较函数以使用存储的值。如果派生键的值是可变的,您可以编写一个属性,在更新基础值时更新键。Here's a function that, given a string with a mixture of alphabetical and numeric parts, returns a tuple that will sort in a "natural" way.
The basic approach it uses is, when it sees a digit, it gathers additional characters and keeps trying to convert the result to a number until it can't anymore (i.e. it gets an exception). By default it tries to convert runs of characters to an integer, but you can pass in
convert=float
to have it accept decimal points. (It won't accept scientific notation, unfortunately, since to get something like '1e3' it would first try to parse '1e' which is invalid. This, along with the + or - sign, could be special-cased but it doesn't look like that is necessary for your use case.)The function returns a tuple containing strings and numbers in the order they were found in the string, with the numbers parsed to the specified numeric type. For example:
This tuple can be used as a key for sorting a list of strings:
Or you can use it to implement a comparison function:
It would be better (faster) to generate the natural key in the object's
__init__()
method, store it in the instance, and write your comparison function(s) to use the stored value instead. If the value from which the key is derived is mutable, you could write a property that updates the key when the underlying value is updated.