Python-根据第一个列表的排序对4个列表进行排序

时间:2020-04-23 19:33:40

标签: python python-3.x list sorting

我有4个列表,想要将第一个列表从最小到最大排序,然后对第二个,第三个和第四个列表应用相同的更改。

例如:

nodeA = ['1', '4', '3', '5' , '2'] nodeB = ['0', '5', '0', '6', '3'] identity = ['R', 'G', 'C', 'L', 'L'] value = ['100', '125', '300', '400', '275']

将转到:

nodeA = ['1', '2', '3', '4' , '5'] nodeB = ['0', '3', '0', '5', '6'] identity = ['R', 'L', 'C', 'G', 'L'] value = ['100', '275', '300', '125', '400']

(我想我做对了)

我不确定该怎么做,非常感谢您的帮助!

6 个答案:

答案 0 :(得分:3)

您可以为Python argsort()创建list版本:

def argsort(seq):
    ix = list(range(len(seq)))
    ix.sort(key=seq.__getitem__)
    return ix

可用于重新排序所有列表:

nodeA = ['1', '4', '3', '5' , '2']
nodeB = ['0', '5', '0', '6', '3']
identity = ['R', 'G', 'C', 'L', 'L']
value = ['100', '125', '300', '400', '275']

ix = argsort(nodeA)
nodeA = [nodeA[i] for i in ix]
nodeB = [nodeB[i] for i in ix]
identity = [identity[i] for i in ix]
value = [value[i] for i in ix]

print(nodeA)
# ['1', '2', '3', '4', '5']
print(nodeB)
# ['0', '3', '0', '5', '6']
print(identity)
# ['R', 'L', 'C', 'G', 'L']
print(value)
# ['100', '275', '300', '125', '400']

答案 1 :(得分:2)

我们可以结合使用zipnumpy来快速做到这一点。

import numpy as np

a, b, c, d = np.transpose(sorted(zip(nodeA, nodeB, identity, value)))

for arr in (a, b, c, d):
    print(arr, '\n')

['1' '2' '3' '4' '5'] 

['0' '3' '0' '5' '6'] 

['R' 'L' 'C' 'G' 'L'] 

['100' '275' '300' '125' '400'] 

我们也可以不使用numpy并使用zip两次。

a, b, c, d = zip(*sorted(zip(nodeA, nodeB, identity, value)))

for arr in (a, b, c, d):
    print(list(arr), '\n')

['1', '2', '3', '4', '5'] 

['0', '3', '0', '5', '6'] 

['R', 'L', 'C', 'G', 'L'] 

['100', '275', '300', '125', '400']

注意:如果所有列表的大小都不相同,则此操作将无法正常工作。

答案 2 :(得分:2)

如果您必须继续使用列表,我建议您查看其他答案。

但是,如果所有列表中的每个索引都与某个对象相关联(我正在想象一个带有两个节点,一个标识和一个测量值的测量设备),那么更复杂的数据结构可能会更好您的选择。

假设您创建了这样的课程Device

class Device:

    def __init__(self, nodeA, nodeB, identity, value):
        self.nodeA = nodeA
        self.nodeB = nodeB
        self.identity = identity
        self.value = value

,然后创建该类的5个实例。

devices = [Device(1, 0, 'R', 100),
           Device(4, 5, 'G', 125),
           Device(3, 0, 'C', 300),
           Device(5, 6, 'L', 400),
           Device(2, 3, 'L', 275)]

然后,您可以使用内置key模块中的内置sorted函数(带有可选的operator参数)和attrgetter函数,轻松地对该列表进行排序。这将按照您作为键给出的函数对对象列表进行排序,特别是获得您要作为排序依据的所需属性的函数。

import operator
sorted_devices = sorted(devices, key=operator.attrgetter('nodeA'))

在这里,设备通过nodeA属性进行排序,但是现在您也可以轻松地通过其他任何属性对其进行排序。

答案 3 :(得分:1)

如果您对性能/内存的要求不严格,并且列表很少且数量固定,则可以尝试使用此脚本,也许这是更容易实现的方法。

nodeA = ['1', '4', '3', '5' , '2']
nodeB = ['0', '5', '0', '6', '3']
identity = ['R', 'G', 'C', 'L', 'L']
value = ['100', '125', '300', '400', '275']

s_A = sorted(nodeA)
s_B = []
s_i = []
s_v = []

for i in range(len(nodeA)):
    index = nodeA.index(s_A[i])
    s_B.append(nodeB[index])
    s_i.append(identity[index])
    s_v.append(value[index])

print(s_A)
print(s_B)
print(s_i)
print(s_v)

答案 4 :(得分:1)

您可以创建一个元组列表并对其进行排序,然后使用其中的信息对其他列表进行排序...

>>> nodeA = ['1', '4', '3', '5' , '2']
>>> tracker = [(item, i) for i, item in enumerate(nodeA)]
>>> tracker.sort()
>>> tracker
[('1', 0), ('2', 4), ('3', 2), ('4', 1), ('5', 3)]

现在,我们有一个在第一项上排序的元组列表,其原始位置为第二项。我们可以将该位置值用作其他列表的索引。

>>> nodeB = ['0', '5', '0', '6', '3']
>>> identity = ['R', 'G', 'C', 'L', 'L']
>>> value = ['100', '125', '300', '400', '275']
>>> 
>>> for li in (nodeA, nodeB, identity, value):
...     li = [li[i] for item, i in tracker]
...     print(li)
...     
['1', '2', '3', '4', '5']
['0', '3', '0', '5', '6']
['R', 'L', 'C', 'G', 'L']
['100', '275', '300', '125', '400']
>>> 

答案 5 :(得分:1)

使用字典映射

d = {}
for a_value, b_value, i_value, value in zip(nodeA, nodeB, identity, value):
    d[a_value]=[b_value,i_value,value]
nodeA = sorted(nodeA)

然后使用刚刚创建的字典再次使用查找值

nodeB=[d.get(i)[0] for i in nodeA] #['0', '3', '0', '5', '6']
identity=[d.get(i)[1] for i in nodeA] #['R', 'L', 'C', 'G', 'L']
value=[d.get(i)[2] for i in nodeA] #['100', '275', '300', '125', '400']