如何在python中按任意方向对多个元组列表进行排序?

2024-06-16 10:09:59 发布

您现在位置:Python中文网/ 问答频道 /正文

所以基本上我有10个列表:5个速率列表和5个开发列表。它们组合成5个列表。名单如下:

rate1 = [16,16,16,0,0,0,0,0,16,16,0,0,0,0,0,0,12,23,34,45,56,67,545,23,34,45,56]
rate2 = [6,6,15,5,5,5,5,5,8,7,7,7,7,7,6,6,2,23,324,415,56,67,545,23,34,48,6]
rate3 = [5,4,3,2,2,0,0,0,8,8,8,8,6,6,6,5,122,23,34,41,5216,67,545,23,34,25,533]
rate4 = [6,5,2,0,0,0,0,0,9,9,9,7,6,6,5,5,1232,23,34,45,56,67,545,23,34,44,38]
rate5 = [0,0,0,0,0,0,0,0,10,9,8,7,6,6,6,2,124,243,324,457,562,7,545,33,64,45,56]

dev1 = [7,2,10,-8,-1,-5,-4,-26,12,7,-14,-21,-16,-15,-19,-20,124,24,34,457,562,7,545,33,64,45,56]
dev2 = [26,19,22,18,17,8,14,26,15,21,29,49,53,30,48,37, 1124,243,24,77,562,7,545,33,64,45,56]
dev3 = [53,54,40,36,57,-8,-1,-5,49,53,48,37,44,90,45,88, 154,213,34,87,572,7,545,33,64,45,56]
dev4 = [53,54,57,-8,-1,-5,-4,-26,49,53,48,90,88,55,61,53, 4,241,374,457,52,7,545,33,64,45,56]
dev5 = [-8,-1,-5,-4,-26,-25,-16,0,90,88,61,79,63,88,82,92, 14,26,324,457,562,7,545,33,64,45,56]

因此,我只编写了一个程序,将rate1与dev1和其余部分结合起来。在我将他们分成5组后,如下所示:

price1 = list(zip(rate1, dev1))
price2 = list(zip(rate2, dev2))
price3 = list(zip(rate3, dev3))
price4 = list(zip(rate4, dev4))
price5 = list(zip(rate5, dev5))

n=5
a = [price1[i:i + n] for i in range(0, len(price1), n)]
b = [price2[i:i + n] for i in range(0, len(price2), n)]
c = [price3[i:i + n] for i in range(0, len(price3), n)]
d = [price4[i:i + n] for i in range(0, len(price4), n)]
e = [price5[i:i + n] for i in range(0, len(price5), n)]
print(a)
print(b)
print(c)
print(d)
print(e)

这样做之后,我得到了5个2d列表,然后我想按降序对它们进行速率排序,得到每个速率列表的前4个速率,从每个速率列表的这4个值中,得到每组的4个最大值,并得到它们相应的dev值,因此我编写了这个程序:

####Sorting the tuples of list rate wise####
newPrice1 = [sorted(block, reverse=True, key=lambda x: x[0])[:4] for block in a]
newPrice2 = [sorted(block, reverse=True, key=lambda x: x[0])[:4] for block in b]
newPrice3 = [sorted(block, reverse=True, key=lambda x: x[0])[:4] for block in c]
newPrice4 = [sorted(block, reverse=True, key=lambda x: x[0])[:4] for block in d]
newPrice5 = [sorted(block, reverse=True, key=lambda x: x[0])[:4] for block in e]

###Getting the max all the list and their coresponding Dev###
rv = []
dv = []
for i in range(0, len(newPrice1)-1):
    rv.append([])
    dv.append([])
    for j in range(4):
        m = max(newPrice1[i][j][0], newPrice2[i][j][0], newPrice3[i][j][0], newPrice4[i][j][0], newPrice5[i][j][0])
        rv[-1].append(m)
        if m == newPrice1[i][j][0]:
            dv[-1].append(newPrice1[i][j][1])

        elif m == newPrice2[i][j][0]:
            dv[-1].append(newPrice3[i][j][1])

        elif m == newPrice3[i][j][0]:
            dv[-1].append(newPrice3[i][j][1])

        elif m == newPrice4[i][j][0]:
            dv[-1].append(newPrice4[i][j][1])

        elif m == newPrice5[i][j][0]:
            dv[-1].append(newPrice5[i][j][1])

print(newPrice1)
print(newPrice2)
print(newPrice3)
print(newPrice4)
print(newPrice5)
print(rv)
print(dv)

输出:

newPrice1 = [[(16, 7), (16, 2), (16, 10), (0, -8)], [(16, 12), (16, 7), (0, -5), (0, -4)], [(0, -14), (0, -21), (0, -16), (0, -15)], [(45, 457), (34, 34), (23, 24), (12, 124)], [(545, 545), (67, 7), (56, 562), (34, 64)], [(56, 56), (45, 45)]]
newPrice2 = [[(15, 22), (6, 26), (6, 19), (5, 18)], [(8, 15), (7, 21), (5, 8), (5, 14)], [(7, 29), (7, 49), (7, 53), (7, 30)], [(415, 77), (324, 24), (23, 243), (6, 37)], [(545, 545), (67, 7), (56, 562), (34, 64)], [(48, 45), (6, 56)]]
newPrice3 = [[(5, 53), (4, 54), (3, 40), (2, 36)], [(8, 49), (8, 53), (0, -8), (0, -1)], [(8, 48), (8, 37), (6, 44), (6, 90)], [(122, 154), (41, 87), (34, 34), (23, 213)], [(5216, 572), (545, 545), (67, 7), (34, 64)], [(533, 56), (25, 45)]]
newPrice4 = [[(6, 53), (5, 54), (2, 57), (0, -8)], [(9, 49), (9, 53), (0, -5), (0, -4)], [(9, 48), (7, 90), (6, 88), (6, 55)], [(1232, 4), (45, 457), (34, 374), (23, 241)], [(545, 545), (67, 7), (56, 52), (34, 64)], [(44, 45), (38, 56)]]
newPrice5 = [[(0, -8), (0, -1), (0, -5), (0, -4)], [(10, 90), (9, 88), (0, -25), (0, -16)], [(8, 61), (7, 79), (6, 63), (6, 88)], [(457, 457), (324, 324), (243, 26), (124, 14)], [(562, 562), (545, 545), (64, 64), (33, 33)], [(56, 56), (45, 45)]]


Rate = [[16, 16, 16, 5], [16, 16, 5, 5], [9, 8, 7, 7], [1232, 324, 243, 124], [5216, 545, 67, 34]]
Dev = [[7, 2, 10, 36], [12, 7, -8, -1], [48, 37, 44, 90], [4, 87, 26, 14], [572, 545, 7, 64]]

因此,费率表实际上是不对的,因为如果你看到第一组新价格,你可以看到最大的数字是16,但在连续3次16,在**第4(第3个索引)**处有5,但实际上那里应该有15,它出现在^{的第0个索引中. 这可能是因为我不是一次拿整个矩阵。预期产出为:

Rate = [[16, 16, 16, 15], [16, 16, 10, 9], [9, 8, 8, 8], [1232, 457, 415, 324], [5216, 562, 545, 545]]
dev = [[7, 2, 10, 22], [12, 7, 90, 49], [48, 48, 61, 37], [4, 457, 77, 24], [572, 562, 545, 545]]

有人能在最后一部分帮助我们从任何方向获得最大值吗


Tags: in列表forlen速率rangeblocklist
2条回答

由于您没有使用newPrice列表中的最后两个元素,我认为我们可以从一开始就忽略它们,这可以让生活更轻松:

>>> from itertools import chain
>>> newPriceArr = []
>>> n = 5
>>> for i in range(1, 6): # because there are lists named from 1 to 5, to access them from globals
        tempList = [
                    sorted(elem, reverse=True, key=lambda x:x[0])[:4] 
                    for elem in 
                    zip(*[
                          iter(
                              zip(
                                 globals()[f"rate{i}"], globals()[f"dev{i}"]
                                 )
                              )
                          ] * n
                        )
                    ]
        newPriceArr.append(tempList)

>>> newPriceArr
# it is now equivalent to [newPrice1, newPrice2, ..., newPrice5]
>>> flattened_arr = [sorted(
                            chain.from_iterable(elem), 
                            reverse=True, 
                            key=lambda x:x[0]
                        )[:4] for elem in zip(*newPriceArr)]
>>> flattened_arr
[[(16, 7), (16, 2), (16, 10), (15, 22)],
 [(16, 12), (16, 7), (10, 90), (9, 49)],
 [(9, 48), (8, 48), (8, 37), (8, 61)],
 [(1232, 4), (457, 457), (415, 77), (324, 24)],
 [(5216, 572), (562, 562), (545, 545), (545, 545)]]
>>> temp = [list(zip(*elem)) for elem in flattened_arr]
>>> temp
[[(16, 16, 16, 15), (7, 2, 10, 22)],
 [(16, 16, 10, 9), (12, 7, 90, 49)],
 [(9, 8, 8, 8), (48, 48, 37, 61)],
 [(1232, 457, 415, 324), (4, 457, 77, 24)],
 [(5216, 562, 545, 545), (572, 562, 545, 545)]]
>>> Rate, dev = list(zip(*temp))
>>> Rate
((16, 16, 16, 15),
 (16, 16, 10, 9),
 (9, 8, 8, 8),
 (1232, 457, 415, 324),
 (5216, 562, 545, 545))
>>> dev
((7, 2, 10, 22),
 (12, 7, 90, 49),
 (48, 48, 37, 61),
 (4, 457, 77, 24),
 (572, 562, 545, 545))
# you can convert these to list later if you want

说明:

本部分:

zip(*[
      iter(
         zip(
            globals()[f"rate{i}"], globals()[f"dev{i}"]
            )
          )
       ] * n
     )

请参见:^{},这基本上是从列表中生成n元素子列表

现在,newPriceArr,正如我前面提到的,持有:

[
 newPrice1,
 newPrice2,
 newPrice3,
 newPrice4,
 newPrice5
]

根据你的数据

Flattened_arr的代码如下所示:

# say we have a list like:
>>> newPrice = [
        [[(10,1), (5,2), (3,1)], [(1,2), (3,5), (6,8)]],   # sub_A
        [[ (9,4), (8,5), (1,0)], [(3,2), (7,6), (0,5)]]    # sub_B
    ]
# Now we need to find top 2 maximum values from each vertical set ([sub_A[i], sub_B[i]]):
# in order to do that, we need to concatenate all the vertical elements into
# a single list, so that we can sort those, to concatenate we do:
>>> list([zip(*newPrice)])
[
([(10, 1), (5, 2), (3, 1)], [(9, 4), (8, 5), (1, 0)]),

 ([(1, 2), (3, 5), (6, 8)], [(3, 2), (7, 6), (0, 5)])
]

# Even though we have grouped the vertical set, but they are in a tuple,
#  and still in their own sublists, we need to truly concatenate those, so
>>> from itertools import chain
>>> [list(chain.from_iterable(elem)) for elem in zip(*newPrice)]
[[(10, 1), (5, 2), (3, 1), (9, 4), (8, 5), (1, 0)],
 [(1, 2), (3, 5), (6, 8), (3, 2), (7, 6), (0, 5)]]
# Now, these are concatenated, now we need to sort
>>> [sorted(chain.from_iterable(elem), reverse=True) for elem in zip(*newPrice)]
[[(10, 1), (9, 4), (8, 5), (5, 2), (3, 1), (1, 0)],
 [(7, 6), (6, 8), (3, 5), (3, 2), (1, 2), (0, 5)]]
# now to select 2 elems
>>> [sorted(chain.from_iterable(elem), reverse=True)[:2] for elem in zip(*newPrice)]
[[(10, 1), (9, 4)], [(7, 6), (6, 8)]] # flattened_arr

这里有一种使用numpy的方法。使用kind='mergesort'是为了在排序中保持先到先得的服务

n = 5
top = 4
m = n*(len(rate1)//n) #assumption that all lists are same length

# array of rate and dev
arr_rate = np.stack([rate1, rate2, rate3, rate4, rate5]).T[:m].reshape(n, -1)
arr_dev = np.stack([dev1, dev2, dev3, dev4, dev5]).T[:m].reshape(n, -1)

# get the idx of top 4 per group of n values
idx = np.argsort(-arr_rate, kind='mergesort')[:, :top]
arange = np.arange(n)[:, None] # for indexing just after

#get the lists as expected
l_rate = arr_rate[arange, idx].tolist()
l_dev = arr_dev[arange, idx].tolist()

print(l_rate)
print (l_dev)
[[16, 16, 16, 15], [16, 16, 10, 9], [9, 8, 8, 8], [1232, 457, 415, 324], [5216, 562, 545, 545]]
[[7, 2, 10, 22], [12, 7, 90, 49], [48, 48, 61, 37], [4, 457, 77, 24], [572, 562, 545, 545]]

相关问题 更多 >