【问题标题】:Python double sort with split string [duplicate]带有拆分字符串的Python双重排序[重复]
【发布时间】:2013-09-12 23:37:56
【问题描述】:

我正在尝试对某些东西进行双重排序,但它似乎忘记了第一个排序,我认为 python 使用的是稳定排序,所以我可能犯了一个错误。

原始文本是一个如下所示的数组:

benzene - 30.0 - 15
xylene - 5.0 - 10
benzene - 8.5 - 29
benzene - 0.5 - 11

我想要:

benzene - 0.5 - 11
benzene - 8.5 - 29
benzene - 30.0 - 15
xylene - 5.0 - 10

这是我的代码:

def akey(a):
    z = a.split(' -')
    v = [z[0]]
    x = [str(i) for i in v]
    return x

def bkey(b):
    z = b.split(' -')
    v = [z[1]]
    x = [float(i) for i in v]
    return x

labelList.sort(key=akey)
labelList.sort(key=bkey)

感谢您的帮助

【问题讨论】:

  • 这不是稳定排序的意思。 1.2 小于 1.3,所以BAC - 1.2 - 10 将排在ABC - 1.3 - 29 之前
  • 稳定排序意味着具有相同键值的任何元素将在单个排序操作期间保持它们相对于彼此的顺序。不保证不同排序的顺序。

标签: python string sorting


【解决方案1】:

正如@NullUserException 所说,您不能分两步进行排序,因为第二步将仅基于中间列重新洗牌,而忽略第一列(str)。

对数据进行适当的转换后,可以一键进行排序,不用担心key:

s='''ABC - 0.2 - 15
BAC - 1.2 - 10
ABC - 1.3 - 29
ABC - 0.7 - 11'''

data = s.split('\n')

data
Out[5]: ['ABC - 0.2 - 15', 'BAC - 1.2 - 10', 'ABC - 1.3 - 29', 'ABC - 0.7 - 11']

newdata = [(i[0],float(i[1]),i[2]) for i in [k.split(' - ') for k in data]]

newdata
Out[10]: 
[('ABC', 0.2, '15'),
 ('BAC', 1.2, '10'),
 ('ABC', 1.3, '29'),
 ('ABC', 0.7, '11')]

sorted(newdata)
Out[11]: 
[('ABC', 0.2, '15'),
 ('ABC', 0.7, '11'),
 ('ABC', 1.3, '29'),
 ('BAC', 1.2, '10')]

另一种方法:如果输入数据重组需要大量操作,则使用 lambda 键可能是更简单的方法:

# data is a list of strings
data = ['ABC - 0.2 - 15', 'BAC - 1.2 - 10', 'ABC - 1.3 - 29', 'ABC - 0.7 - 11']

# My key is now a lambda function that extracts the 
# sortable parts, and assembles them in a tuple.
# Note how easy it would be to change the sort order,
# just order the entries in the inner tuple differently.
# If data is some other array-like structure, just change
# how the inner data is accessed when building your tuple.

sorted(data, key=lambda x: (x.split(' - ')[0], float(x.split(' - ')[1])))
Out[18]: ['ABC - 0.2 - 15', 'ABC - 0.7 - 11', 'ABC - 1.3 - 29', 'BAC - 1.2 - 10']

【讨论】:

  • 问题是我的原始数据是一个数组,所以我不能在它上面运行.split。否则你的解决方案会起作用
  • 如果您使用数据的确切形式更新您的问题(例如,提供您目前拥有的四个元素),我将更新我的答案。
  • 当您说“数组”时,您的意思是listarray.arraynumpy.ndarray 还是“文件中的行”?
【解决方案2】:

你为什么不尝试先放 bkey,然后放 akey

基本上你有 2 个优先级来对它们进行排序......你最左边的优先级更高。所以如果你从右边开始排序,就会得到你想要的结果。

【讨论】:

  • 已经试过了,只是颠倒了顺序,忘记了第一个排序
  • @user2774582 这应该确实有效。首先按 bkey 排序,然后按 akey。
  • 啊!想通了问题。这确实有效,但我第一次尝试时认为它不起作用的原因是因为它将“苯”与“BENZENE”分开分类,这就是我认为它不起作用的原因。我也无法发现这个问题,因为我的最终输出是全部大写的。谢谢大家,原始代码确实有效。
【解决方案3】:

您可以通过拆分将每个字符串转换为列表,然后以标准方式对这些列表进行排序:

>>> l = ["ABC - 0.2 - 15", "BAC - 1.2 - 10", "ABC - 1.3 - 29", "ABC - 0.7 - 11"]
>>> l.sort(key=lambda x: x.split(' - ')[:2])
>>> l
['ABC - 0.2 - 15', 'ABC - 0.7 - 11', 'ABC - 1.3 - 29', 'BAC - 1.2 - 10']

【讨论】:

    猜你喜欢
    • 2021-02-10
    • 1970-01-01
    • 2015-05-12
    • 2023-02-06
    • 2015-11-06
    • 2019-02-03
    • 2011-05-23
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多