有什么方法可以排序如何对 3 元素元组列表进行排序

问题描述 投票:0回答:2

我有一个 3 元素元组的列表,像这样: lst = [(0, 0, 'C'), (0, 1, 'C'), (0, 2, 'C'), (0, 3, 'C'), (0, 4, 'C '), (1, 0, 'C'), (1, 4, 'C'), (1, 1, 'B'), (1, 2, 'B'), (1, 3, 'B '), (2, 0, 'C'), (2, 4, 'C'), (2, 1, 'B'), (2, 3, 'B'), (2, 2, 'A '), (3, 0, 'C'), (3, 4, 'C'), (3, 1, 'B'), (3, 2, 'B'), (3, 3, 'B '), (4, 0, 'C'), (4, 1, 'C'), (4, 2, 'C'), (4, 3, 'C'), (4, 4, 'C' ')] 前两个元素是行、列,第三个是我应该在这些坐标中打印的字母。

我设法使用带有 lambda 函数作为关键参数的排序函数按行(上面的列表)对未排序的原始列表进行排序,但是在尝试对列进行排序时,我陷入了困境。 我需要对前两个元素进行排序,以便它们形成这样的矩阵 (0,1,"C"),(0,2,"C"),(0,3,"C"),(0,4 "C"),(1,0,"C"),(1,1,"B"),(1,2,"B"),(1,3,"B"),(1,4 "C"), 等等... 感谢您对此的建议。

python list sorting multidimensional-array tuples
2个回答
0
投票

你在问两个不同的问题。我会回答两个。

有什么方法可以排序如何对 3 元素元组列表进行排序?

是的。只需使用

sorted
。请参阅Python 排序方法

lst = [(3, 0, 'C'), (0, 3, 'C'), (2, 2, 'A'), (3, 4, 'C'), (1, 3, 'B'), (0, 0, 'C'), (0, 4, 'C'), (0, 1, 'C'), (3, 2, 'B'), (4, 4, 'C'), (4, 2, 'C'), (1, 4, 'C'), (2, 1, 'B'), (1, 1, 'B'), (4, 0, 'C'), (4, 3, 'C'), (2, 3, 'B'), (4, 1, 'C'), (0, 2, 'C'), (3, 3, 'B'), (2, 4, 'C'), (1, 2, 'B'), (1, 0, 'C'), (2, 0, 'C'), (3, 1, 'B')]

lst.sort()

print(lst)
# [(0, 0, 'C'), (0, 1, 'C'), (0, 2, 'C'), (0, 3, 'C'), (0, 4, 'C'),
#  (1, 0, 'C'), (1, 1, 'B'), (1, 2, 'B'), (1, 3, 'B'), (1, 4, 'C'),
#  (2, 0, 'C'), (2, 1, 'B'), (2, 2, 'A'), (2, 3, 'B'), (2, 4, 'C'),
#  (3, 0, 'C'), (3, 1, 'B'), (3, 2, 'B'), (3, 3, 'B'), (3, 4, 'C'),
#  (4, 0, 'C'), (4, 1, 'C'), (4, 2, 'C'), (4, 3, 'C'), (4, 4, 'C')]

前两个元素是行、列,第三个是我应该在这些坐标中打印的字母。

只需构建一个适当尺寸的二维数组

a
,最初用零填充。然后迭代三元组
(row, column, element)
并影响
element
a[row][column]
.

lst = [(3, 0, 'C'), (0, 3, 'C'), (2, 2, 'A'), (3, 4, 'C'), (1, 3, 'B'), (0, 0, 'C'), (0, 4, 'C'), (0, 1, 'C'), (3, 2, 'B'), (4, 4, 'C'), (4, 2, 'C'), (1, 4, 'C'), (2, 1, 'B'), (1, 1, 'B'), (4, 0, 'C'), (4, 3, 'C'), (2, 3, 'B'), (4, 1, 'C'), (0, 2, 'C'), (3, 3, 'B'), (2, 4, 'C'), (1, 2, 'B'), (1, 0, 'C'), (2, 0, 'C'), (3, 1, 'B')]

height = 1+max(row for row,_,_ in lst)
width = 1+max(col for _,col,_ in lst)
a = [[0 for col in range(width)] for row in range(height)]
for row, col, element in lst:
    a[row][col] = element
print(a)
# [['C', 'C', 'C', 'C', 'C'],
#  ['C', 'B', 'B', 'B', 'C'],
#  ['C', 'B', 'A', 'B', 'C'],
#  ['C', 'B', 'B', 'B', 'C'],
#  ['C', 'C', 'C', 'C', 'C']]

请注意,您实际上可以将这两种方法结合起来。

因为你有一个 5x5 的数组要填充,而你的列表恰好有 25 个元素,那么一旦元素被排序,你不需要记住

row
col
索引,你可以每 5 个拆分列表元素:

lst = [(3, 0, 'C'), (0, 3, 'C'), (2, 2, 'A'), (3, 4, 'C'), (1, 3, 'B'), (0, 0, 'C'), (0, 4, 'C'), (0, 1, 'C'), (3, 2, 'B'), (4, 4, 'C'), (4, 2, 'C'), (1, 4, 'C'), (2, 1, 'B'), (1, 1, 'B'), (4, 0, 'C'), (4, 3, 'C'), (2, 3, 'B'), (4, 1, 'C'), (0, 2, 'C'), (3, 3, 'B'), (2, 4, 'C'), (1, 2, 'B'), (1, 0, 'C'), (2, 0, 'C'), (3, 1, 'B')]

height = 5 #  = 1+max(row for row,_,_ in lst)
width = 5  #  = 1+max(col for _,col,_ in lst)
a = [e for _,_,e in sorted(lst)]
a = [a[i:i+width] for i in range(height)]
print(a)
# [['C', 'C', 'C', 'C', 'C'],
#  ['C', 'C', 'C', 'C', 'C'],
#  ['C', 'C', 'C', 'C', 'B'],
#  ['C', 'C', 'C', 'B', 'B'],
#  ['C', 'C', 'B', 'B', 'B']]

0
投票

这些元组的简单排序将按行/列顺序对它们进行排序。基于这些排序后的值,您可以通过对列表进行切片来构建结果矩阵。

lst.sort()

M = [ [V for _,_,V in row] for row in zip(*[iter(lst)]*(lst[-1][1]+1)) ]

print(*M,sep="\n")

['C', 'C', 'C', 'C', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'B', 'A', 'B', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'C', 'C', 'C', 'C']
  • 一旦列表按行/列顺序排序,最后一项具有最大的行号和列号,因此可以用它来确定每行的大小(通过将列号加1):
    (lst[-1][1]+1)
  • 要对列表进行切片,您可以通过给它一个迭代器来使用 zip() ,您可以根据列的数量重复多次。 zip 返回的每个元组将包含接下来的 N 个值,有效地生成行。
  • 由于您只希望矩阵包含元组的字母,因此使用嵌套列表推导提取元组的第三个元素:
    [V for _,_,V in row]

为了更易于管理,您可以将流程分解为更小的步骤:

lst.sort()
width      = lst[-1][1]+1               # number of columns
_,_,values = zip(*lst)                  # values (letters) only
slices     = zip(*[iter(values)]*width) # slice into list of row tuples
matrix     = list(map(list,slices))     # convert row slices to list of lists

print(*matrix,sep="\n")

['C', 'C', 'C', 'C', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'B', 'A', 'B', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'C', 'C', 'C', 'C']

请注意,以这种方式构建矩阵需要

lst
为矩阵中的每个单元格包含一个元组。

...

如果

lst
不包含每个坐标的值,则矩阵必须预先存在(即不是从列表创建的)。无法保证
lst
中的坐标始终到达最后一行或最后一列,因此我们无法根据列表可靠地计算维度。鉴于此,事先对列表进行排序没有意义,分配循环足以更新现有矩阵中的单元格

另一种构建矩阵的有趣方法是使用 itertools 中的 groupby 函数:

from itertools import groupby

rows,_,values = map(iter,zip(*sorted(lst)))
M = [ row for _,[*row,] in groupby(values,lambda _:next(rows)) ]

print(*M,sep="\n")
['C', 'C', 'C', 'C', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'B', 'A', 'B', 'C']
['C', 'B', 'B', 'B', 'C']
['C', 'C', 'C', 'C', 'C']
© www.soinside.com 2019 - 2024. All rights reserved.