Ruby按条件排序问题:如何修复自定义排序代码?
Hey there! Let's figure out how to fix your array sorting code. You want to sort elements first by the number of 1s in their binary representation, then by their decimal value when the 1 counts are equal—totally makes sense. Let's break down the problem and the fix.
Common Issue in the Original Code
Most likely, your original code only uses the count of 1s as the sort key. This means when two elements have the same number of 1s, their order depends on their original position (since Python's sort is stable) instead of their decimal value. That's the gap we need to close.
The Fix: Use a Tuple as the Sort Key
Python's sort() and sorted() functions let you use a tuple as the sort key. When comparing tuples, Python checks the first element first—only if those are equal does it move to the second element. This is exactly what we need: first sort by the count of 1s, then by the element's decimal value.
Example: From Broken to Fixed Code
Let's start with a broken version that only sorts by 1s count:
# Broken code: Only considers binary 1s count, ignores decimal order arr = [10, 6, 11, 4, 1] arr.sort(key=lambda x: bin(x).count('1')) print(arr) # Output: [4, 1, 10, 6, 11] → Wrong! 1 should come before 4
Now fix it by using a tuple key:
# Fixed code: First sort by 1s count, then by decimal value arr = [10, 6, 11, 4, 1] arr.sort(key=lambda x: (bin(x).count('1'), x)) print(arr) # Output: [1, 4, 6, 10, 11] → Perfect!
How It Works
bin(x).count('1')calculates how many 1s are in the binary string ofx—super straightforward in Python.- The tuple
(bin(x).count('1'), x)tells the sort function:- First group elements by the number of 1s in their binary form.
- Within each group, sort elements by their actual decimal value.
Bonus: More Efficient 1s Count (Optional)
If you're working with very large numbers and want a faster way to count 1s (instead of converting to a string), you can use a bitwise operation trick:
def count_binary_ones(n): count = 0 while n: n &= n - 1 # Clears the least significant 1 bit count += 1 return count # Use this function in the sort key arr.sort(key=lambda x: (count_binary_ones(x), x))
This is more efficient for big integers, but bin(x).count('1') is totally fine for most everyday use cases—it's clean and easy to read.
Using sorted() Instead of list.sort()
If you want a new sorted array instead of modifying the original one, the logic is identical with sorted():
arr = [10, 6, 11, 4, 1] sorted_arr = sorted(arr, key=lambda x: (bin(x).count('1'), x)) print(sorted_arr) # Same correct output: [1, 4, 6, 10, 11]
内容的提问来源于stack exchange,提问作者Moacir Petry

