学生が持っている点数のリストがあります。
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 ++ ...)
マークを受け取り、人間が読める表現を返す関数を定義します。 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
忘れる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つのリストで成績と成績を取得できます。
_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')]
_
独自のフィルターのような関数を書くことができます:
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)