2018年01月14日

言語処理100本ノックでPython入門 #02 - for, zip, enumerate

   このエントリーをはてなブックマークに追加 Clip to Evernote
言語処理100本ノックの問題02をやりました。

■問題


第1章: 準備運動

02. 「パトカー」+「タクシー」=「パタトクカシーー」
「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

■書いたコード

s1 = 'パトカー'
s2 = 'タクシー'
s3 = ""
for a, b in zip(s1, s2):
    s3 += a + b
print(s3)

■実行結果

パタトクカシーー

■今回学習したこと


文字列は、シングルクォートで括ってもOK.
実際に、ここ(https://docs.python.jp/3/reference/index.html)を見たら確かにそう書いてありました。

この問題は、C#だったらLINQのZipメソッド使う場面ですね。Zipと似たような機能がないかな〜と探したらありました。

zip関数をfor文とともに使えば、2つのシーケンスから同時に値を取り出すことができます。これ、めちゃくちゃ便利ですね。
pythonのfor文は、C#でいうとforeachにあたるんですね。

実は、初めに書いたのは、以下のようなコード
s1 = 'パトカー'
s2 = 'タクシー'
s3 = ""
for i, e in enumerate(s1):
    s3 += e + s2[i]
print(s3)

zip関数ではなく、enumerate関数使ってます。 こうすると、文字列を1文字ずつ列挙するとともに、インデックスもあわせて列挙できます。
これはこれで便利な機能ですね。どこかで使えそうです。

ちなみに、以下のように書けば、s1から1文字ずつ文字を取り出せます。
for e in s1:
    print(e)

これが、pythonのfor文の基本ですね。

じゃあ、C#でいう普通のfor文はどうやって書くのかなと思ったら、そのような構文は無いみたいです。
どうしても必要ならば、range関数でシーケンスを生成すればOK.
for i in range(10):
    print(i)

これで、0から9までを列挙できます。
次のように書けば、1から9までを列挙できます。

for i in range(1, 10): print(i)

次のような書き方もできます。これでも、s1の中の文字を1文字ずつ列挙できます。
for i in range(len(s1)):
    print(s1[i])

でもこのコードは、以下のように「enumerate使ってね」と警告がでます。pylint良くできてますね。
message: 'C0200:Consider using enumerate instead of iterating with range and len'

今回はいろんなことを学習できました。