英文:
sorting with a condition Grade Letters
问题
我正在尝试对成绩等级进行排序,其中B+必须在B之前等。
import random
grades = ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
random.shuffle(grades)
print(grades)
['C', 'B', 'F', 'B+', 'D+', 'A', 'A-', 'C-', 'C+', 'B-', 'D']
使用sorted
函数会将B排在B+之前等。
我使用了key
与sorted
函数,但不知道如何使用它!
sorted(grades, key=lambda x: x.endswith('+'))
任何帮助都将不胜感激。
我搜索了很多类似的问题,但都没有成功!
英文:
I am trying to sort grade letters where B+ must be before B etc.
import random
grades = ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
random.shuffle(grades)
print(grades)
['C', 'B', 'F', 'B+', 'D+', 'A', 'A-', 'C-', 'C+', 'B-', 'D']
Using sorted
function brings B before B+, etc.
I used the key
with sorted function but I am not aware how exactly to use it!
sorted(grades, key=lambda x: x.endswith('+'))
Any help is appreciated.
I searched a lot for a similar question without success!
答案1
得分: 4
- 使用
bool
值的int
值,
- 如果有
+
,它将是-1
- 如果有
-
,它将是1
- 如果没有以上情况,它将是0
-
使用映射字典将符号转换为要排序的数字:
lettermap = {'-': 2, '': 1, '+': 0} grades.sort(key=lambda x: (x[0], lettermap[x[1:]])) # 用于多个排序条件的元组 print(grades) # ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
-
内联字典的方法相同
grades.sort(key=lambda x: (x[0], {'-': 2, '': 1, '+': 0}[x[1:]])) grades.sort(key=lambda x: (x[0], {'-': 2, '+': 0}.get(x[1:], 1)))
英文:
- Use the
int
value frombool
,
-
if there is
+
it'll be-1
-
if there is
-
it'll be1
-
if none of, it'll be 0
<!-- -->
grades.sort(key=lambda x: (x[0], - x.endswith('+') + x.endswith('-')))
-
Using a mapping dict to convert sign to a number to be sorted :
lettermap = {'-': 2, '': 1, '+': 0} grades.sort(key=lambda x: (x[0], lettermap[x[1:]])) # tuple to have multiple criterias print(grades) # ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
-
Same with inline dict
grades.sort(key=lambda x: (x[0], {'-': 2, '': 1, '+': 0}[x[1:]])) grades.sort(key=lambda x: (x[0], {'-': 2, '+': 0}.get(x[1:], 1)))
答案2
得分: 2
关键函数将元素映射到实数,然后sort
函数将根据这些值对列表中的元素进行排序。为了为sort
函数生成这样的keys
,尝试将字母映射为整数,例如使用ord
,如果后面有符号,调整这些值为小数!
def keyfunc(grade):
value = ord(grade[0]) # 每个字母都映射到一个数字
if len(grade) > 1:
if grade[1] == '+': # 加号等级排名较高 -> 减少一点
value -= 0.3
else:
value += 0.3 # 减号等级,增加一点
return value
sorted(grades, key=keyfunc)
这将产生以下结果:
['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
英文:
The key function maps the elements to real numbers, the sort
function will then sort the elements in your list by those values. In order to produce such keys
for the sort
function, try mapping the letters to integers e.g. with ord
and adjust those values to decimals if there is a sign after!
def keyfunc(grade):
value = ord(grade[0]) #every letter gets mapped to a number
if len(grade)>1:
if grade[1] == '+': #plus grades rank higher -> subtract a little
value -= 0.3
else:
value += 0.3 #for minus , add a little
return value
sorted(grades, key=keyfunc)
this produces:
['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
答案3
得分: 2
你可以使用dict.get
并提供一个默认返回值:
sorted(grades, key=lambda g: (g[0], {'-': 2, '+': 0}.get(g[-1], 1)))
英文:
You could use dict.get
and supply a default return:
sorted(grades, key=lambda g: (g[0], {'-': 2, '+': 0}.get(g[-1], 1)))
答案4
得分: 1
Alternatively, you could map each of the letter grades directly to a numerical value and sort based on that:
mapping = {'A': 10, 'A-': 9, 'B+': 8, 'B': 7, 'B-': 6, 'C+': 5, 'C': 4, 'C-': 3, 'D+': 2, 'D': 1, 'F': 0}
sorted(grades, key=lambda x: mapping[x.upper()], reverse=True)
# ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
英文:
Alternatively, you could map each of the letter grades directly to a numerical value and sort based on that:
mapping = {'A': 10, 'A-': 9, 'B+': 8, 'B': 7, 'B-': 6, 'C+': 5, 'C': 4, 'C-': 3, 'D+': 2, 'D': 1, 'F': 0}
sorted(grades, key=lambda x: mapping[x.upper()], reverse=True)
# ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'F']
答案5
得分: 1
以下是翻译好的代码部分:
改进版的 @peer 的答案。更多的情况处理,如 'A+' > 'b-' 和诸如 "A++" 的成绩。
def grade_valuator(grade):
postgrade = grade.upper()
value = 0
i = 2
while(len(postgrade) > 0):
if postgrade[0] == '+':
value -= .5 ** i
i += 1
elif postgrade[0] == '-':
value += .5 ** i
i += 1
elif postgrade[0].isalnum():
value += ord(postgrade[0])
postgrade = postgrade[1:]
return value
代码使用示例:
grades = ['+d', 'b+', 'A', 'A-', 'C-', 'C', 'A+', 'C++', 'b-', 'A++', 'D', 'E', 'B', 'C+', 'C+-', 'F', '--C']
sorted(grades, key=grade_valuator) # 获取新的排序后的列表副本
# ['A++', 'A+', 'A', 'A-', 'b+', 'B', 'b-', 'C++', 'C+', 'C+-', 'C', 'C-', '--C', '+d', 'D', 'E', 'F']
print(grades)
# ['+d', 'b+', 'A', 'A-', 'C-', 'C', 'A+', 'C++', 'b-', 'A++', 'D', 'E', 'B', 'C+', 'C+-', 'F', '--C']
grades.sort(key=grade_valuator) # 就地对列表进行排序
print(grades)
# ['A++', 'A+', 'A', 'A-', 'b+', 'B', 'b-', 'C++', 'C+', 'C+-', 'C', 'C-', '--C', '+d', 'D', 'E', 'F']
英文:
Enhanced version of @peer's answer. More case handling like 'A+' > 'b-' and grades such as "A++".
def grade_valuator(grade):
postgrade = grade.upper()
value = 0
i = 2
while(len(postgrade) > 0):
if postgrade[0] == '+':
value -= .5 ** i
i += 1
elif postgrade[0] == '-':
value += .5 ** i
i += 1
elif postgrade[0].isalnum():
value += ord(postgrade[0])
postgrade = postgrade[1:]
return value
Code use examples:
grades = ['+d', 'b+', 'A', 'A-', 'C-', 'C', 'A+', 'C++', 'b-', 'A++', 'D', 'E', 'B', 'C+', 'C+-', 'F', '--C']
sorted(grades, key=grade_valuator) #Get a new sorted copy of the list
#['A++', 'A+', 'A', 'A-', 'b+', 'B', 'b-', 'C++', 'C+', 'C+-', 'C', 'C-', '--C', '+d', 'D', 'E', 'F']
print(grades)
#['+d', 'b+', 'A', 'A-', 'C-', 'C', 'A+', 'C++', 'b-', 'A++', 'D', 'E', 'B', 'C+', 'C+-', 'F', '--C']
grades.sort(key=grade_valuator) #Sort the list in-place
print(grades)
#['A++', 'A+', 'A', 'A-', 'b+', 'B', 'b-', 'C++', 'C+', 'C+-', 'C', 'C-', '--C', '+d', 'D', 'E', 'F']
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论