本講座では極力覚えることは少なくして、早く動くプログラムを作れるようになることに主眼を置いています。そのため、コードが少し冗長になっても基本的な道具を使うことを優先しています。

しかし、プログラミングに慣れてきたら、Pythonに数ある便利な機能を利用した方が、コードを短く読みやすく書けるようになります。既に基本は十分理解しているのでより有効に活用できます。

今回は、受講後にすぐに活用できて便利な3つのワザ(enumerate( )関数、リスト内包表記、パッキングとアンパッキング)を紹介します。

本記事の目次

enumerate( )関数 と zip( )関数

ループの回数が知りたい時に便利な enumerate( )関数

リストをループする時に、一緒にインデックス番号が必要な場合は、以下のようにidx変数に毎回1を足すのがもっとも単純は方法です。

>>> lst = ["a", "b", "c", "d", "e"]
>>> idx = 0
>>> for v in lst:
        print(idx, v)
        idx = idx + 1

0 a
1 b
2 c
3 d
4 e

同じ結果のコードを、組み込み関数のenumerate()関数を使うと、わざわざidxを作成しないで可能になります。idxを1つずつ増やす手間もかかりません。

>>> for i, v in enumerate(lst):
        print(i, v)

0 a
1 b
2 c
3 d
4 e

デフォルトでは番号は0から始まりますが、start=で任意に指定できます。

>>> for i, v in enumerate(lst, start=5):
        print(i, v)

5 a
6 b
7 c
8 d
9 e

講座の「CSVファイルをエクセルに転記するプログラム」では

行と列のインデックス用に変数(r_idx、c_idx)を用いましたが、このenumerate( )関数を使うと0で初期化したりループごとに1を増やす必要がなくなります。

複数のリストを一緒にループできる zip( )関数

組み込みのzip()関数を利用すると、複数のリストやタプルを並列して一緒にループすることができます。

>>> a_lst = ["a", "b", "c", "d", "e"]
>>> b_lst = [1, 2, 3, 4, 5]
>>> for a, b in zip(a_lst, b_lst):
        print(a, b)
 
a 1
b 2
c 3
d 4
e 5

同じ処理を zip()関数利用しないで enumerate()関数 でプログラミングすると、以下のように他方のリストの要素をインデックスで取得する必要があります。

>>> for i, a in enumerate(a_lst):
        b = b_lst[i]
        print(a, b)
 
a 1
b 2
c 3
d 4
e 5

このzip()関数を活用すると、以下のように「2つのリストから1つの辞書を作る」ことが簡単にできます。

>>> dic = {}
>>> for a, b in zip(a_lst, b_lst):
...     dic[a] = b
... 
>>> dic
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

リスト内包表記

既存のリストからある条件を満たす要素だけを取り出して新しいリストを作成するには、以下のように空のリストを作成しておいて、そこに条件に合う要素を追加します。

>>> towns = ["akasaka", "aoyama", "roppongi", "shibuya", "azabu"]
>>> a_towns = []
>>> for t in towns:
        if t.startswith("a"):
            a_towns.append(t)

>>> a_towns
['akasaka', 'aoyama', 'azabu']

同じ処理を「リスト内包表記」という表記法を用いて、ループ処理を1行に繋げて書くことができます。

>>> a_towns = [t for t in towns if t.startswith("a") ]
>>> a_towns
['akasaka', 'aoyama', 'azabu']

以下のように何らかの処理を加えて、新しいリストを作成することも容易になります。

>>> a_towns_1chome = [t + "_1chome" for t in towns if t.startswith("a") ]
>>> a_towns_1chome
['akasaka_1chome', 'aoyama_1chome', 'azabu_1chome']

if文以降の条件式を除けば、全ての要素について処理したリストを作成できます。

>>> towns_1chome = [t + "_1chome" for t in towns]
>>> towns_1chome
['akasaka_1chome', 'aoyama_1chome', 'roppongi_1chome', 'shibuya_1chome', 'azabu_1chome']

パッキングとアンパッキング

タプルのデータを作成するには、以下のように丸かっこを用います。これは、各要素を1つの変数に「梱包」する作業にたとえて、パッキング(packing)と呼びます。

>>> t1 = ("a", "b", "c")
>>> t1
('a', 'b', 'c')

タプルのパッキングは丸かっこを省略できます。

>>> t2 = "a", "b", "c"
>>> t2
('a', 'b', 'c')

一方、以下のように要素の数だけ変数をカンマで区切り、タプルを代入すると「開梱」できます。これは、アンパッキング(unpacking)と呼びます。

>>> x, y, z = t1
>>> x
'a'
>>> y
'b'
>>> z
'c'

アンパッキングはタプルだけでなく、リストのようなシーケンス全般で可能です。

>>> lst = [1, 10, 100]
>>> i, j, k = lst
>>> i
1
>>> j
10
>>> k
100

パッキングとアンパッキングを等号で繋ぎ同時に行うと、複数の変数に一度に代入できて便利です。

>>> x, y, z = 2, 4, 8
>>> x
2
>>> y
4
>>> z
8

さらに、関数の戻り値に用いることで、複数の値を返すことが可能になります。

>>> def powers(x):
        return x**0, x**1, x**2, x**3, x**4, x**5, x**6, x**7

>>> v = powers(2)
>>> v
(1, 2, 4, 8, 16, 32, 64, 128)
>>> v[3]
8

ちなみに上のタプルと同じ要素の「2のべき乗のリスト」は、リスト内包表記を使うと以下のように書けます。

>>> s = [2**x for x in range(8)]
>>> s
[1, 2, 4, 8, 16, 32, 64, 128]

最後に

Pythonは進化しているプログラミング言語なので、他にも便利な機能はありますが、まず今回紹介した3つのテクニックを活用してみてください。かなりプログラミングが捗るようになります!