Pythonでenumerateを賢く使う。
enumerateって?
英語で『数え上げる』という意味です。この関数の引数にイテレータを与えると、何回そのイテレータを呼び出したかを数える数と、そのイテレータ自身を返します。
例えば
for i, j in enumerate(range(5, 0, -1)): print(i, j) """ 0 5 1 4 2 3 3 2 4 1 """
rangeの特異な使い方については、こちらをご覧ください
delta114514.hatenablog.jp
となります。 i には 呼び出し回数が、j にはイテレータ(今回は、特にジェネレータです)の値が入っています。
ちなみに、enumerateは引数を二つ取ります。二つ目は、1番初めの番号を決めます。
for i, j in enumerate(range(5, 0, -1), start=5): print(i, j) """ 5 5 6 4 7 3 8 2 9 1 """
これを使うと、AtCoderのこのC問題なら2行で解くことができます。
C - 背の順
問題文
高橋学級には N 人の生徒がいます。 生徒は 1 から N まで出席番号が振られています。 i 番目の生徒の身長は a_i です。 a_i はすべて相異なります。
高橋先生は N 人の生徒を背の高い方から順に並べました。 N 人の生徒の出席番号を背の高い方から順に出力してください。制約
2≦N≦10^5
ai は整数である。
1≦a_i≦10^9
a_i はすべて相異なる。部分点
30 点分のテストケースでは、N≦1000 を満たす。
入力
入力は以下の形式で標準入力から与えられる。
N
a_1 a_2 … a_N出力
N 行出力せよ。 i 行目には、i 番目に背の高い生徒の出席番号を出力せよ。
はい。
愚直にやると
n = int(input()) individuals = list(map(int, input().split())) for i in range(n): tallest = max(individuals) number = individuals.index(tallest) # tallestを直に入れても良いです print(number + 1) individuals[number] = 0
背の高い人を毎回割り出して、その番号を返し、身長をブラックホール圧縮することでカウントしないようにしています。
ですが、こちら、TLEしてしまいました。
悲しいなぁ…
ですが、このenumerateを使う方法ならTLEせずに解けます。
n=int(input()) for i in sorted(enumerate(list(map(int, input().split())), start=1), key = lambda x :x[1], reverse = True): print(i[0])
lambdaについては
delta114514.hatenablog.jp
をご覧ください
わかりやすくすると
def getsecond(n): # lambdaの明示化 return n[1] n = int(input()) individuals = list(map(int, input().split())) # 入力 enumerated_individuals = list(enumerate(individuals, start=1)) # enumerateされたlistを作る enumerated_individuals.sort(key=getsecond, reverse=True) # 身長でsortする for i in enumerated_individuals: print(i[0])
です。つまり、身長と、入力された順番で対応したlistを作り、身長でsort(番号はくっついたまま)することにより、上から取り出すことで、番号のみを取り出すことができます。
各実行ごとでは
def getsecond(n): # lambdaの明示化 return n[1] n = int(input()) individuals = list(map(int, input().split())) # 入力 # individuals == [[160, 120, 150, 170]] enumerated_individuals = list(enumerate(individuals, start=1)) # enumerateされたlistを作る #enumerated_individuals == [(1, 160), (2, 120), (3, 150), (4, 170)] enumerated_individuals.sort(key=getsecond, reverse=True) # 身長でsortする #enumerated_individuals == [(4, 170), (1, 160), (3, 150), (2, 120)] for i in enumerated_individuals: print(i[0])
となります。
いいでしょ~、enumerate!!
それではみなさん、よいPythonLifeを!
宣伝…
#Python3 パーカーを作りたいと思っています。
— ながたさん.py🐍 (@nagataaaas) 2018年2月10日
購入したい!という人が多ければ安く作れるので、いいなぁ、と思えば、リプでもDMでもどうぞ!
I wanna make the "#Python hoody". And I want YOU to buy one, too. cuz' lots of buyer make the hoody more inexpensive. give me contact #パーカー pic.twitter.com/0ElGJetNcb