2018年01月23日

言語処理100本ノックでPython入門 #06 - 集合演算

  
今日は言語処理100本ノックの問題06です。

■ 問題
06. 集合
"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を,それぞれ, XとYとして求め,XとYの和集合,積集合,差集合を求めよ.さらに,'se'というbi-gramがXおよびYに含まれるかどうかを調べよ.
■ 書いたコード
def ngram(s, n):
    items = []
    last = len(s) - n + 1
    for i in range(last):
        items.append(s[i: i+n])
    return items

text1 = "paraparaparadise"
text2 = "paragraph"
x = set(ngram(text1, 2))
y = set(ngram(text2, 2))

print("x:", x)
print("y:", y)

union = x | y
print("\n和集合(x | y):")
print(union)

intersection = x & y
print("\n積集合(x & y):")
print(intersection)

difference1 = x - y
print("\n差集合(x - y):")
print(difference1)

print('')
print('seがxに含まれる:', ('se' in x))

issubset = {'se'} <= y
print('seがyに含まれる:', issubset)

ソースコードは、GitHubで公開しています。

■ 実行結果
x: {'se', 'ap', 'is', 'di', 'pa', 'ra', 'ar', 'ad'}
y: {'gr', 'ap', 'ag', 'pa', 'ra', 'ar', 'ph'}

和集合(x | y): {'se', 'gr', 'ra', 'ar', 'ad', 'ap', 'is', 'di', 'ag', 'pa', 'ph'}
積集合(x & y): {'ra', 'ar', 'ap', 'pa'}
差集合(x - y): {'se', 'is', 'di', 'ad'}
seがxに含まれる: True seがyに含まれる: False

■ 今回学んだこと


集合演算を行うには、配列をset関数で、集合に変換します。
x = set([1, 2, 3, 4, 5])
集合演算は、演算子を使う方法と、メソッド呼び出しの2種類あるようです。

和集合
union1 = x | y
union2 = x.union(y)
積集合
intersection1 = x & y
intersection2 = x.intersection(y) 
差集合
difference1 = x - y
difference2 = x.difference(y)
包含
subset1 = {'se', 'ap'} <= x
subset2 = {'se', 'ap'}.issubset(x)
# 単独の要素ならば、in 演算子が使える
subset3 = 'se' in x
<= 演算子って、ちょっと違和感ありますね。
今まで触った言語の中で、集合演算子で使われているのってたぶんこれは初めてかも。 

print関数は、複数の引数を受け取れる

print関数は、print(a, b) のように複数の引数を受け取れるんですね。便利です。
この場合は、引数の間に一つの空白文字が挿入されるようです。


先頭行のブレークポイントを解除する

それと、Visual Studio Codeでデバッグする時に、いつも先頭行で実行が一時停止になってしまうんですが、これをやめるには、launch.jsonで、次のような設定をすればOKです。
    "configurations": [
        {
            "name": "Python",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,    // ココをfalseに変更
           ...