我正在尝试根据列表{% for item in menu_items %}
<li>
<a href="{% if item.specific.link and item.specific.link != '' %}{{ item.specific.link }}{% elif item.specific_class == 'Node'%}#{% else %}{% pageurl item %}{% endif %}">{{ item.title }
</a>
</li>
{% endfor %}
的排序来对列表B
进行排序。棘手的部分是列表A
的排序是分步进行的。
我曾尝试压缩列表,但无法正常工作。
列表A
的排序是这样的:
A
正在发生以下情况:
steps = [0, 1, 3, 5]
B = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
A = [['X', 'Y'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y']
for i in range(len(steps)-1):
A[steps[i]:steps[i + 1]] = sorted(A[steps[i]:steps[i + 1]], key = len, reverse=True)
中的子列表0根据长度以相反的顺序排序,然后是子列表1,2,然后是3,4,最后是5,6。
答案 0 :(得分:1)
您可以使用zip对列表进行排序,只需要一个可以解释这些对的键函数即可。然后,在对对进行排序后,您可以使用zip“解压缩”它们
B = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
A = [['X', 'Y'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y']]
def lenRight(pair):
return len(pair[1])
C = sorted(zip(B,A), key = lenRight)
B_sorted, A_sorted = zip(*C)
print(B_sorted)
print(A_sorted)
这将输出:
('B', 'E', 'A', 'G', 'C', 'D', 'F')
(['X'], ['X'], ['X', 'Y'], ['X', 'Y'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'])
编辑:
我现在明白了,
steps = [1, 3, 5]
B = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
A = [['X', 'Y'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X'], ['X', 'Y', 'Z'], ['X', 'Y']]
lastStep = 0
sortedLists = []
def lenRight(pair):
return len(pair[1])
for step in steps:
C = sorted(zip(B[lastStep:lastStep+step],A[lastStep:lastStep+step]), key = lenRight, reverse = True)
B_sorted, A_sorted = zip(*C)
sortedLists.append((A_sorted, B_sorted))
lastStep = step
for pair in sortedLists:
A_sort, B_sort = pair
print(A_sort, B_sort)
输出:
(['X', 'Y'],) ('A',)
(['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X']) ('C', 'D', 'B')
(['X', 'Y', 'Z'], ['X', 'Y', 'Z'], ['X', 'Y'], ['X']) ('D', 'F', 'G', 'E')
答案 1 :(得分:1)
假设A
中的所有对象都是可哈希的且唯一的:
A
和B
一起压缩到列表C
中,并将该列表移到一边。A
进行排序。不用担心B
或C
A
项的反向查找字典,将其放在排序算法所处的位置。 B
进行排序。 A = [29, 42, 17]
B = ['bravo', 'charlie', 'alpha']
C = list(zip(A, B))
A.sort() # replace with your mystery sorter
lookup = {a:index for (index, a) in enumerate(A)}
for (a, b) in C:
index = lookup[a]
B[index] = b
print(A)
print(B)
#output
[17, 29, 42]
['alpha', 'bravo', 'charlie']
构建C
,构建查找字典以及最后组织B
的成本都是O(n)
免责声明:不喜欢写回B
。宁愿写一个大小合适的新列表。
更新:上面的代码仅在A中没有重复项时有效。下面的代码段通过附加一个唯一性(原始索引)来处理重复项。尽管这行得通,但是这种方法太复杂了。您也可以将A和B的邮政编码排序在一起,这在另一个答案中进行了描述。
A = [29, 42, 29, 17]
B = ['bravo1', 'charlie', 'bravo2', 'alpha']
A2 = [(index, a) for index,a in enumerate(A)]
C = list(zip(A, B))
A2.sort(key=lambda t : t[1] ) # replace with your mystery sorter, which has to deal with tuples now
A = [a for (_, a) in A2]
lookup = {t:index for (index, t) in enumerate(A2)}
for original_index, (a, b) in enumerate(C):
new_index = lookup[original_index, a]
B[new_index] = b
print(A)
print(B)
#output
[17, 29, 29, 42]
['alpha', 'bravo1', 'bravo2', 'charlie']
为了完整起见,下面的代码是我必须处理A中的重复项时真正要做的事情。这实质上是发布的另一个答案。
A = [29, 42, 29, 17]
B = ['bravo1', 'charlie', 'bravo2', 'alpha']
C = list(zip(A, B))
C.sort(key=lambda t : t[0] ) # replace with your mystery sorter, which has to deal with a zip of A and B together
[A, B] = zip(*C)
print(A)
print(B)