基于优先级规则的元素排序问题:如何实现双条件分步排序?
Hey there! Let's break down your sorting problem and get that code working as expected.
The Problem Setup
You've got:
- An element list:
element = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - Two feature arrays:
C1 = [0, 0, 1, 0, 1, 0, 0, 1, 0, 1]C2 = [15, 35, 40, 20, 17, 45, 30, 18, 41, 35]
Your sorting priority rules are clear:
- First, all elements where
C1[i] == 1should come first (keeping their original relative order) - Then, from the remaining elements, those with
C2[i] >= 40come next (again, preserving original order) - Finally, the rest follow in their original order
You're aiming for this result: order1 = [2, 4, 7, 9, 5, 8, 0, 1, 3, 6]
What's Wrong With the Original Code?
Your initial approach of shifting elements via insert/delete has two big issues:
- The variable
insertion_position1isn't initialized at all—this would throw aNameErrorright away - Even if you initialized it, modifying the list while iterating over its original indices messes up position tracking. By deleting and inserting elements mid-loop, you shift the indices of the elements you haven't checked yet, leading to incorrect ordering (like the
[2, 4, 5, 7, 8, 9, ...]result you got)
Better Solutions
Option 1: Use Python's sorted() with a Custom Key (Cleanest Approach)
Instead of manually shifting elements, leverage Python's built-in sorted() function with a custom key tuple that enforces your priority rules. This is concise, readable, and avoids index chaos:
element = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] C1 = [0, 0, 1, 0, 1, 0, 0, 1, 0, 1] C2 = [15, 35, 40, 20, 17, 45, 30, 18, 41, 35] # Define a key that sorts by your priority rules order1 = sorted( range(len(element)), key=lambda i: (-C1[i], -(C2[i] >= 40), i) ) print(order1) # Output: [2, 4, 7, 9, 5, 8, 0, 1, 3, 6]
How This Works:
The key is a tuple where each element represents a priority level (left = highest priority):
-C1[i]: ConvertsC1[i] = 1to-1and0to0. Since-1 < 0, allC1=1elements sort first.-(C2[i] >= 40): ConvertsTrue(whenC2[i] >=40) to-1andFalseto0. This pushes qualifying elements to the front of their group.i: Acts as a tiebreaker—if two elements have the same priority, they stay in their original order (this is called "stable sorting").
Option 2: Fixed Insert/Delete Approach (If You Prefer This Style)
If you want to stick with the insert/delete method, split the process into two separate passes. This avoids index shifting issues by handling one priority group at a time:
element = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] C1 = [0, 0, 1, 0, 1, 0, 0, 1, 0, 1] C2 = [15, 35, 40, 20, 17, 45, 30, 18, 41, 35] order1 = list(range(len(element))) insertion_pos = 0 # First pass: Move all C1[i] == 1 elements to the front for i in range(len(element)): if C1[i] == 1: # Find the current index of this element in order1 idx = order1.index(i) temp = order1.pop(idx) order1.insert(insertion_pos, temp) insertion_pos += 1 # Second pass: Move remaining C2[i] >=40 elements next for i in range(len(element)): if C1[i] != 1 and C2[i] >= 40: idx = order1.index(i) temp = order1.pop(idx) order1.insert(insertion_pos, temp) insertion_pos += 1 print(order1) # Output: [2, 4, 7, 9, 5, 8, 0, 1, 3, 6]
This works because we handle all first-priority elements before touching the second group, so we don't mess up index tracking during each pass.
内容的提问来源于stack exchange,提问作者Anis Boudieb

