Python: 辞書のキーや値の型・文字列パターンを判定

 Pythonの辞書のキーもしくは値の型がすべて数値や文字列など特定の型であることを保証するために、辞書の値/キーをリストにし、各要素の型を判定し、その論理積を求めて値/キー全体の型の判定を行う。

結論

data = {'a':1, 'b':2, 'c':3}

のような辞書データの値がすべてint(整数)であるかチェックをするには以下のように記述すれば良い。

all(map(isinstance,data.values(),[int]*len(data)))

 キーを判定するならば、values()keys()にする。型を文字列や他の型にしたければ、intstrなどにする。

 文字列パターンの判定をするには正規表現でpatternを指定して以下のように記述する。

all(map(bool, map(re.match, [pattern]*len(data), data.keys())))

解説

型の判定

all(map(isinstance,data.values(),[int]*len(data)))

 適用している関数を内側から見ていくと、

  1. values():辞書の値を[1, 2, 3]のようにリストで取得する
  2. isinstance(obj, class_or_tuple):リストの値がintであるかを論理値(True/False)で取得する
  3. map(func, *iterables):関数をリストの各要素に適用し、要素ごとの結果をリストで取得する
  4. all(iterable):リストの全要素がTrueのときのみTrueとなる、つまりFalseが一つ以上あればFalseとなる

 map関数を適用する際に、isinstance関数には引数が2つあるため、map(func, iterable1, iterable2)の形式で書く必要がある。ここで2つ目の引数は、各要素がすべてintであるdataと同じ長さのリストを与えている。これにより、
isinstance(1, int)isinstance(2, int)isinstance(3, int)
の結果がリストで取得される。

 Pythonで論理値配列を引数とする論理演算をする際には、
 論理積all(list)
 論理和any(list)
を用いる。

文字列パターンの判定

 日付など時間をキーとする場合、文字列で表記されることが多く、表記がそろっているか判定することがある。

data = {'8/22/2016': 0, '8/23/2016':1}

のような辞書データにおいて、キーである日付の表記がそろっているか判定をするには、re.match(pattern, string)を利用して以下のように記述する。

import re
pattern = '^\d+/\d+/\d+$'
all(map(bool, map(re.match, [pattern]*len(data), data.keys())))

 正規表現によるパターンの書き方については正規表現操作にそって任意のパターンを書くと良い。

 re.match関数は直接に論理値を返さないため、map関数でbool(x)を適用している。