第131回【Python】連想配列、連想配列(query)

現在取り組んでいるのは、paiza ラーニング問題集「クエリメニュー」になります。

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 131 回目です。

時々、社用車の鍵が消えます。前回の利用者が鍵をポケットに入れたまま返し忘れたのでしょう。LeoSaki(旦那)は社外に出て打ち合わせをすることは少ないので社用車を使う機会が少ないのですが、予定が入っている人は大慌てです。

それでは、今日も頑張ってみようと思います。

連想配列

3xxx 年、ロボット学校の先生である paiza 君は、新しく担当するクラスの生徒一人一人の出席番号と識別 ID を覚えるように言われました。
具体的には、出席番号が与えられたら、その生徒の識別 ID を言えるようになる必要があります。
覚えるべき生徒の出席番号と識別 ID のペアが与えられたのち、いくつか出席番号が与えられるので、各番号に対応する生徒の識別 ID を出力してください。

N K
num_1 ID_1
...
num_N ID_N
Q_1
...
Q_K

・1 行目では、生徒の人数 N と与えられる出席番号の個数 K が与えられます。
・続く N 行のうち i 行目 (1 ≦ i ≦ N) では、i 番目の生徒の出席番号と識別 ID の組 num_i , ID_i が半角スペース区切りで与えられます。
・続く K 行では、出席番号 Q_i (1 ≦ i ≦ K) が与えられます。


すべてのテストケースにおいて、以下の条件をみたします。

・1 ≦ N , K ≦ 1,000
・0 ≦ num_i ≦ 10,000 (1 ≦ i ≦ N)
・num_i ≠ num_j (i ≠ j)
・ID_i は アルファベット大文字小文字(a ~ z , A ~ Z)と数字(0 ~ 9)から成る 20 文字以下の文字列 (1 ≦ i ≦ N)
・全ての Q_i について、その番号を出席番号として持つ生徒が必ず存在する。


入力例

4 2
1 Sin
2 Sakura
3 Kayo
4 Yui
4
2

出力例

Yui
Sakura

ロボットたちが通う学校なのか、ロボットが教鞭をとっている学校なのか。1000 年後は予想もつかない世界になっているようです。

Python
N,K = map(int,input().split())
dic = {}

for _ in range(N):
    num,ID = input().split()
    dic[num] = ID
    
for _ in range(K):
    Q = input()
    print(dic[Q])
VBA
Sub query_primer__map_easy()

    NK = Split(Cells(1, 1), " ")
    N = Val(NK(0))
    K = Val(NK(1))
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    For i = 1 To N
        s = Split(Cells(i + 1, 1), " ")
        num = Val(s(0))
        ID = s(1)
        dic.add num, ID
    Next
    
    For i = 1 To K
        Q = Cells(i + N + 1, 1)
        Debug.Print dic(Q)
    Next
    
End Sub

連想配列(query)

3xxx年、ロボット学校の先生である paiza 君は、新しく担当するクラスの生徒一人一人の出席番号と識別 ID を覚えて、出席番号が与えられたら、その生徒の識別 ID を言えるようになる必要があります。
paiza 君の務める学校は転校が多く、頻繁に生徒が増減します。

覚えるべき生徒の出席番号と識別 ID が与えられたのち、いくつかのイベントを表す文字列が与えられるので、与えられた順に各イベントに応じて次のような処理をおこなってください。

join num id
生徒番号 num , 識別ID id の生徒を新たに覚える

leave num
生徒番号 num の生徒を忘れる

call num
生徒番号 num の生徒の識別 ID を出力する

N K
num_1 ID_1
...
num_N ID_N
S_1
...
S_K

・1 行目では、初めに覚える生徒の人数 N と与えられるイベントの回数 K が与えられます。
・続く N 行のうち i 行目 (1 ≦ i ≦ N) では、i 番目の生徒の出席番号と識別 ID の組 num_i , ID_i が半角スペース区切りで与えられます。
・続く K 行では、起きるイベントを表す文字列 S_i (1 ≦ i ≦ K) が与えられます。


すべてのテストケースにおいて、以下の条件をみたします。

・1 ≦ N , K ≦ 100,000
・1 ≦ num_i ≦ 1,000,000 (1 ≦ i ≦ N)
・num_i ≠ num_j (i ≠ j)
・ID_i は アルファベット大文字小文字と数字から成る 20 文字以下の文字列 (1 ≦ i ≦ N)
・S_i は次のいずれかの形式である。

・join num id
生徒番号 num , 識別 ID id の生徒を新たに覚える。

・leave num
生徒番号 num の生徒を忘れる。

・call num
生徒番号 num の生徒の識別 ID を出力する。
この時点で生徒番号 num の生徒がいることは保証されている。

1 ≦ num ≦ 1,000,000
id は 20 文字以下の文字列

入力例

4 4
1 Sin
2 Sakura
3 Kayo
4 Yui
call 4
leave 2
join 2 Sakuya
call 2

出力例

Yui
Sakuya

生徒番号が最大 100 万。それを覚えたり忘れたり瞬時に言わされたり、過酷な労働環境の模様。

Python
N,K = map(int,input().split())
dic = { num:ID for num,ID in [input().split() for _ in range(N)] }

for _ in range(K):
    S = input().split()
    query = S[0]
    num = S[1]
    if query == 'join':
        ID = S[2]
        dic[num] = ID
    elif query == 'leave':
        del dic[num]
    elif query == 'call':
        print(dic[num])
VBA
Sub query_primer__map_normal()

    NK = Split(Cells(1, 1), " ")
    N = Val(NK(0))
    K = Val(NK(1))
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    For i = 1 To N
        s = Split(Cells(i + 1, 1), " ")
        num = s(0)
        ID = s(1)
        dic.add num, ID
    Next
    
    For i = 1 To K
        s = Split(Cells(i + N + 1, 1), " ")
        q = s(0)
        num = s(1)
        If q = "join" Then
            ID = s(2)
            dic.add num, ID
        ElseIf q = "leave" Then
            dic.Remove num
        ElseIf q = "call" Then
            Debug.Print dic(num)
        End If
    Next
    
End Sub

最後に

Python で辞書型を作成する際に、1 問目は for 文で回して、2 問目は内包表記で書いてみた。内包表記の方が早いらしい。こういう書き方は Python 独特で面白いと思う。ただ、普段 Python を使ってない人に見せたら何をやっているかよくわからないと言われるので注意。

VBA も Debug.Print に時間がかかっているだけで、それ以外の処理部分は思った以上に高速だ。まだまだ VBA の可能性を感じさせられる結果となっている。

引き続き、よろしくお願いいたします!

Pythonpaiza,学習,Python

Posted by LeoSaki