web-dev-qa-db-ja.com

pythonリストの数値を成績に変換する

学生が持っている点数のリストがあります。

s = [50,62,15,76,57,97,82,99,45,23]

マークに従って学生を採点したい:

<40 - Fail
>50 - A Grade
>75 - A++ Grade

ループを繰り返すことでこれを行うか、ラムダを使用してすべてのリストを見つけることができます。例えば ​​:

>>> filter(lambda x:x>=50, s)
[50, 62, 76, 57, 97, 82, 99]

しかし、フィルターでは、一度に1つの関数しか処理できません(たとえば、50を超えるマーク)。フィルターとラムダを使用して必要な結果を1行で取得できる方法はありますか?グレード付きのマークとして出力を期待しています。 (例:50-A、62-A、76-A ++ ...)

19
sam

マークを受け取り、人間が読める表現を返す関数を定義します。 larsmansの式 またはこれを使用できます。

def grade(i):
    if i<40: return "Fail"
    if i>75: return "A++"
    if i>50: return "A"

String.formatを使用して各エントリをフォーマットし、マップしてそれらすべてを反復します。

li = map(lambda x: "{0} - {1}".format(x, grade(x)), s)

結果のリストには、希望する形式の文字列が含まれています。

for i in li: print i

# output

50 - None
62 - A
15 - Fail
76 - A++
57 - A
97 - A++
82 - A++
99 - A++
45 - None
23 - Fail
21
Mizipzor

忘れるlambda、忘れるfilter;以下は、Aと「不合格」の間にBグレードがあると仮定して、1つの式でグレーディングを行います。

["fail" if g < 40 else "B" if g < 60 else "A" if g < 75 else "A++" for g in s]

この結果をZipを使用してsすると、1つのリストで成績と成績を取得できます。

15
Fred Foo
_s = [50,62,15,76,57,97,82,99,45,23]
x = dict([(a, 'A++' if a>75 else 'A' if a>55 else 'F') for a in s])

print x

{97: 'A++', 45: 'F', 99: 'A++', 76: 'A++', 82: 'A++', 15: 'F', 50: 'F', 23: 'F', 57: 'A', 62: 'A'}
_

たとえば、x.items()を使用してフィルターをかけます。

_filter(lambda x: x[1] == 'A', x.items())
_

結果は

_[(57, 'A'), (62, 'A')]
_
2
bill

独自のフィルターのような関数を書くことができます:

def filter_n(n, f, lst):
    result = Tuple([[] for i in range(n)])
    for elem in lst:
        result[f(elem)].append(elem)
    return result

答えは次のようになっています:

grades = filter_n(3, lambda x: (x < 40) * 0 +
                               (60 < x <= 75) * 1 +
                               (75 < x) * 2, s)
1
citxx