python - 按规则列表排序一些元素的列表
问题描述
我得到了一个元素列表,比如[C, D, B, A]
(每个字母都是一个 RGB 颜色的元组)和一个规则列表(第一个元素 > 第二个元素)
:,[(D,C), (D,B), (D,A), (C,B), (C,A), (B,A)]
所以D
必须排在C
,B
并且A
(所以排在最后)之后,C
在B
and之后A
, (将其放在第 3 位)等。
正确的顺序是[A, B, C, D]
:
for _ in colors:
color += [_]
for element in rules:
listtwo += [(element)]
for x in listtwo:
if x[0] in color:
color.remove(x[0])
if x[1] in color:
color.remove(x[1])
for elements in rules:
if elements[0] == elements[1]:
pass
else:
listone += [elements]
for el in listone:
pos_a = colors.index(el[0])
pos_b = colors.index(el[1])
if pos_a > pos_b:
colors.remove(el[0])
colors.insert(posizione_b, el[0])
if len(color) > 0:
colors.remove(colors[0])
colors.reverse()
if len(color) > 0:
colors.append(colors[0])
它适用于某些特定情况,但不适用于一般情况(并且代码编写得不好)。有任何想法吗?
进一步的例子,它适用于:
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255), (255, 255, 0)]
rules = [
((0, 0, 255), (255, 0, 0)),
((0, 0, 255), (0, 255, 0)),
((0, 255, 0), (255, 0, 0)),
((255, 255, 0), (0, 0, 255)),
((255, 255, 0), (255, 0, 0)),
((255, 255, 0), (0, 255, 0)),
((0, 255, 255), (0, 0, 255)),
((0, 255, 255), (255, 0, 0)),
((0, 255, 255), (0, 255, 0)),
((255, 255, 0), (0, 255, 255))
]
输出是:
[(255, 0, 0), (0, 255, 0), (0, 0, 255), (0, 255, 255), (255, 255, 0)]
它不适用于此示例:
colors = [
(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227),
(79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210),
(127, 219, 167), (222, 190, 134), (191, 52, 233)
]
rules = [
((79, 247, 87), (250, 150, 227)),
((250, 150, 227), (149, 198, 219)),
((79, 247, 87), (149, 198, 219)),
((79, 247, 87), (133, 228, 115)),
((149, 198, 219), (133, 228, 115)),
((133, 228, 115), (142, 150, 92)),
((250, 150, 227), (142, 150, 92)),
((79, 247, 87), (142, 150, 92)),
((197, 223, 252), (142, 150, 92)),
((197, 223, 252), (250, 150, 227)),
((121, 154, 210), (79, 247, 87)),
((121, 154, 210), (197, 223, 252)),
((121, 154, 210), (142, 150, 92)),
((127, 219, 167), (121, 154, 210)),
((197, 223, 252), (79, 247, 87)),
((127, 219, 167), (79, 247, 87)),
((127, 219, 167), (142, 150, 92)),
((121, 154, 210), (104, 132, 238)),
((104, 132, 238), (197, 223, 252)),
((127, 219, 167), (197, 223, 252)),
((222, 190, 134), (121, 154, 210)),
((191, 52, 233), (121, 154, 210)),
((222, 190, 134), (191, 52, 233)),
((191, 52, 233), (127, 219, 167)),
((191, 52, 233), (222, 190, 134))
]
错误的输出:
[(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227),
(79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210),
(127, 219, 167), (222, 190, 134), (191, 52, 233)]
正确的输出:
[(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227),
(79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210),
(127, 219, 167), (191, 52, 233), (222, 190, 134)]
解决方案
您可以使用graphlib.TopologicalSorter
Python 3.9 中引入的:
ts = TopologicalSorter()
for color in colors:
ts.add(color)
for rule in rules:
ts.add(*rule)
ordered = list(ts.static_order())
但是,根据您的规则,这会导致错误
graphlib.CycleError: ('nodes are in a cycle', [(191, 52, 233), (222, 190, 134), (191, 52, 233)])
这也是Martijn指出的。
但是,如果您删除不正确的规则,那么它会给您预期的结果。
演示:
from graphlib import TopologicalSorter
colors = [(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227), (79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210), (127, 219, 167), (222, 190, 134), (191, 52, 233)]
rules = [((79, 247, 87), (250, 150, 227)), ((250, 150, 227), (149, 198, 219)), ((79, 247, 87), (149, 198, 219)), ((79, 247, 87), (133, 228, 115)), ((149, 198, 219), (133, 228, 115)), ((133, 228, 115), (142, 150, 92)), ((250, 150, 227), (142, 150, 92)), ((79, 247, 87), (142, 150, 92)), ((197, 223, 252), (142, 150, 92)), ((197, 223, 252), (250, 150, 227)), ((121, 154, 210), (79, 247, 87)), ((121, 154, 210), (197, 223, 252)), ((121, 154, 210), (142, 150, 92)), ((127, 219, 167), (121, 154, 210)), ((197, 223, 252), (79, 247, 87)), ((127, 219, 167), (79, 247, 87)), ((127, 219, 167), (142, 150, 92)), ((121, 154, 210), (104, 132, 238)), ((104, 132, 238), (197, 223, 252)), ((127, 219, 167), (197, 223, 252)), ((222, 190, 134), (121, 154, 210)), ((191, 52, 233), (121, 154, 210)), ((222, 190, 134), (191, 52, 233)), ((191, 52, 233), (127, 219, 167)), ((191, 52, 233), (222, 190, 134))]
expect = [(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227), (79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210), (127, 219, 167), (191, 52, 233), (222, 190, 134)]
rules.remove(((191, 52, 233), (222, 190, 134)))
ts = TopologicalSorter()
for color in colors:
ts.add(color)
for rule in rules:
ts.add(*rule)
ordered = list(ts.static_order())
print(ordered)
print(ordered == expect)
输出:
[(142, 150, 92), (133, 228, 115), (149, 198, 219), (250, 150, 227), (79, 247, 87), (197, 223, 252), (104, 132, 238), (121, 154, 210), (127, 219, 167), (191, 52, 233), (222, 190, 134)]
True
推荐阅读
- python-3.x - 获取 Python 数组键文本
- azure-devops - Azure DevOps 各种管道
- c# - 定期和异步运行 C# 中线程不安全的函数
- reactjs - 将上下文拆分为状态并更新以提高性能(减少渲染)?
- keras - 与 Keras 和 Cudnn 的卷积——cudnn 卷积方法中是否有填充类型参数?
- php - 未找到列:1054 'where 子句'Laravel 5.6 中的未知列'id'
- gradle - Gradle 文档:没有 @since 版本
- mysql - 在节点 js 中使用 sequelize 创建更新审查
- android - 单击后退按钮时,如何删除活动分配的所有资源
- django - Django:从相关对象注释排名