【问题标题】:How to Sort alphanumeric strings in numpy matrix and list in Python?如何在 Python 中对 numpy 矩阵和列表中的字母数字字符串进行排序?
【发布时间】:2020-07-22 23:41:27
【问题描述】:

我有一个从具有 3 个功能键的 dict 转换而来的列表,例如

{('consumer0', 'consumer0', 0): 0}

要对列表进行排序,我所做的是

    time = np.arange(1)
    agent = ['consumer0', 'consumer10', 'consumer11', 'consumer20',
             'consumer1', 'consumer2', 'consumer3', 'consumer4',
             'consumer5', 'consumer6', 'consumer7', 'consumer8',
             'consumer9']
    P_nm = {}
    for t in time:
        for p1 in agents:
            for p2 in agents:
                P_nm[p1, p2, t] = t

    P_nm = [(k, v) for k, v in P_nm.items()]
    P_nm.sort(key=lambda k: (k[0][2], k[0][0], k[0][1]))

我得到如下结果:

[(('consumer0', 'consumer0', 0), 0), 
 (('consumer0', 'consumer1', 0), 0), 
 (('consumer0', 'consumer10', 0), 0), 
 (('consumer0', 'consumer11', 0), 0), 
 (('consumer0', 'consumer2', 0), 0), 
 (('consumer0', 'consumer20', 0), 0), 
 (('consumer0', 'consumer3', 0), 0),
 ...]

如何对列表进行排序并获得类似的结果

[(('consumer0', 'consumer0', 0), 0), 
 (('consumer0', 'consumer1', 0), 0), 
 (('consumer0', 'consumer2', 0), 0), 
 (('consumer0', 'consumer3', 0), 0), 
 (('consumer0', 'consumer4', 0), 0),
 ...
 (('consumer0', 'consumer10', 0), 0), 
 (('consumer0', 'consumer11', 0), 0)
 ...
]

【问题讨论】:

  • 如果字符串是固定长度的,你可以试试sorted(l, key=lambda x: (x[0][2], int(x[0][0][8:]), int(x[0][1][8:])))。否则,我会推荐re 提取数字
  • 在初始声明agents = ["consumer{0}".format(i_s) for i_s in sorted([int(o.replace("consumer", "")) for o in agents])] 之后直接对代理列表进行排序并删除P_nm = [(k,v) for k,v in P_nm.items()] 行,我认为因为您没有任何索引而更具可读性
  • 您应该对您的消费者编号(例如 consumer09)进行零填充,以确保它们按您的预期排序
  • 非常感谢克里斯!它非常适合这种情况,有效!

标签: python sorting


【解决方案1】:

有一个名为natsort 的库可以完全满足您的需求。它的作用类似于@Chris's comment 的建议,但以更通用的方式,涵盖更多corner cases

natsort 在 anaconda 和 PyPi 中可用,所以 conda install natsortpip install natsort 应该都可以工作。

要使用它,请从natsorted 函数开始,类似于内置的sorted,但具有您想要的功能。

mylist = [
    (('consumer0', 'consumer0', 0), 0), 
    (('consumer0', 'consumer1', 0), 0), 
    (('consumer0', 'consumer10', 0), 0), 
    (('consumer0', 'consumer11', 0), 0), 
    (('consumer0', 'consumer2', 0), 0), 
    (('consumer0', 'consumer20', 0), 0), 
    (('consumer0', 'consumer3', 0), 0),
    ...
]
mylist = natsorted(mylist, key=lambda item: item[0][:2])

由于natsort 在解包元素结构方面非常聪明,您的情况可以简化为

mylist = natsorted(mylist)

由于这可能会出现,我不是 natsort 的作者(this guy 是)。只是一个快乐的用户。

【讨论】:

    猜你喜欢
    • 2013-06-26
    • 1970-01-01
    • 2018-09-03
    • 2018-04-09
    • 2022-11-23
    • 2013-02-09
    • 2021-02-21
    • 2021-02-22
    • 1970-01-01
    相关资源
    最近更新 更多