按照条件排序等级字母

huangapple go评论78阅读模式
英文:

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+之前等。
我使用了keysorted函数,但不知道如何使用它!

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

  1. 使用bool值的int值,
  • 如果有+,它将是-1
  • 如果有-,它将是1
  • 如果没有以上情况,它将是0
  1. 使用映射字典将符号转换为要排序的数字:

     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)))
    
英文:
  1. Use the int value from bool,
  • if there is + it'll be -1

  • if there is - it'll be 1

  • if none of, it'll be 0

    <!-- -->

    grades.sort(key=lambda x: (x[0], - x.endswith(&#39;+&#39;) + x.endswith(&#39;-&#39;)))
    
  1. Using a mapping dict to convert sign to a number to be sorted :

     lettermap = {&#39;-&#39;: 2, &#39;&#39;: 1, &#39;+&#39;: 0}
     grades.sort(key=lambda x: (x[0], lettermap[x[1:]])) # tuple to have multiple criterias
     print(grades) # [&#39;A&#39;, &#39;A-&#39;, &#39;B+&#39;, &#39;B&#39;, &#39;B-&#39;, &#39;C+&#39;, &#39;C&#39;, &#39;C-&#39;, &#39;D+&#39;, &#39;D&#39;, &#39;F&#39;]
    
  • Same with inline dict

          grades.sort(key=lambda x: (x[0], {&#39;-&#39;: 2, &#39;&#39;: 1, &#39;+&#39;: 0}[x[1:]]))
          grades.sort(key=lambda x: (x[0], {&#39;-&#39;: 2, &#39;+&#39;: 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)&gt;1:
        if grade[1] == &#39;+&#39;: #plus grades rank higher -&gt; subtract a little
            value -= 0.3
        else:
            value += 0.3 #for minus , add a little
    return value
sorted(grades, key=keyfunc)

this produces:

[&#39;A&#39;, &#39;A-&#39;, &#39;B+&#39;, &#39;B&#39;, &#39;B-&#39;, &#39;C+&#39;, &#39;C&#39;, &#39;C-&#39;, &#39;D+&#39;, &#39;D&#39;, &#39;F&#39;]

答案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], {&#39;-&#39;: 2, &#39;+&#39;: 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 = {&#39;A&#39;: 10, &#39;A-&#39;: 9, &#39;B+&#39;: 8, &#39;B&#39;: 7, &#39;B-&#39;: 6, &#39;C+&#39;: 5, &#39;C&#39;: 4, &#39;C-&#39;: 3, &#39;D+&#39;: 2, &#39;D&#39;: 1, &#39;F&#39;: 0}

sorted(grades, key=lambda x: mapping[x.upper()], reverse=True)
# [&#39;A&#39;, &#39;A-&#39;, &#39;B+&#39;, &#39;B&#39;, &#39;B-&#39;, &#39;C+&#39;, &#39;C&#39;, &#39;C-&#39;, &#39;D+&#39;, &#39;D&#39;, &#39;F&#39;]

答案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) &gt; 0):
        if postgrade[0] == &#39;+&#39;:
            value -= .5 ** i
            i += 1
        elif postgrade[0] == &#39;-&#39;:
            value += .5 ** i
            i += 1
        elif postgrade[0].isalnum():
            value += ord(postgrade[0])
        postgrade = postgrade[1:]
    return value

Code use examples:

grades = [&#39;+d&#39;, &#39;b+&#39;, &#39;A&#39;, &#39;A-&#39;, &#39;C-&#39;, &#39;C&#39;, &#39;A+&#39;, &#39;C++&#39;, &#39;b-&#39;, &#39;A++&#39;, &#39;D&#39;, &#39;E&#39;, &#39;B&#39;, &#39;C+&#39;, &#39;C+-&#39;, &#39;F&#39;, &#39;--C&#39;]


sorted(grades, key=grade_valuator) #Get a new sorted copy of the list
#[&#39;A++&#39;, &#39;A+&#39;, &#39;A&#39;, &#39;A-&#39;, &#39;b+&#39;, &#39;B&#39;, &#39;b-&#39;, &#39;C++&#39;, &#39;C+&#39;, &#39;C+-&#39;, &#39;C&#39;, &#39;C-&#39;, &#39;--C&#39;, &#39;+d&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;]

print(grades)
#[&#39;+d&#39;, &#39;b+&#39;, &#39;A&#39;, &#39;A-&#39;, &#39;C-&#39;, &#39;C&#39;, &#39;A+&#39;, &#39;C++&#39;, &#39;b-&#39;, &#39;A++&#39;, &#39;D&#39;, &#39;E&#39;, &#39;B&#39;, &#39;C+&#39;, &#39;C+-&#39;, &#39;F&#39;, &#39;--C&#39;]

grades.sort(key=grade_valuator) #Sort the list in-place
print(grades)
#[&#39;A++&#39;, &#39;A+&#39;, &#39;A&#39;, &#39;A-&#39;, &#39;b+&#39;, &#39;B&#39;, &#39;b-&#39;, &#39;C++&#39;, &#39;C+&#39;, &#39;C+-&#39;, &#39;C&#39;, &#39;C-&#39;, &#39;--C&#39;, &#39;+d&#39;, &#39;D&#39;, &#39;E&#39;, &#39;F&#39;]

huangapple
  • 本文由 发表于 2020年1月4日 00:03:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581655.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定