Developer

【Python独学】セットの操作&frozenset型について
2020.11.02
Lv1

【Python独学】セットの操作&frozenset型について

今回は、セット(集合)について以下の2つをみていきましょう。

  • セットの操作
  • frozenset型について

セットの操作

前回の記事までは、セットの作成や要素の追加/削除などの方法をみてきました。
ここでは、以下のようにセットで扱えるメソッドをいくつか確認してみましょう。

・要素数を求める
・最大/最小の要素を求める
・要素を並び替える


要素数を求める

セットの要素数を求めるには len() を使用します。リストやタプルと同様ですね。
例をみてみましょう。

set_test = {"Django", "Flask", "Bottle"}

print(len(set_test))
C:\Python> python 9-3_1.py
3

このように、引数として指定したセットの要素数を求めることができます。
以下のように set() を用いてリストをセットに変換すれば、
重複した要素を省いたリストの要素数を調べたりするような使い方も可能です。

list_test = ["Python", "Java", "Python", "C#", "C#", "Java", "Python", "PHP"]
set_test = set(list_test)

list_count = len(list_test)
set_count = len(set_test)

print("リストの要素数:" + str(list_count))
print("リストから重複を省いた要素数:" + str(set_count))
C:\Python> python 9-3_2.py
リストの要素数:8
リストから重複を省いた要素数:4

最大/最小の要素を求める

セットに含まれる要素の中で、最大の要素を求める場合は max()
最小の要素を求める場合は min() を使用します。

set_num = {1, 20, 100}

print(max(set_num))          ### 最大の要素
print(min(set_num))          ### 最小の要素
C:\Python> python 9-3_3.py
100
1

max() / min() については、要素が1種類のデータ型のみで構成されているときだけ使用できます。
int型とstr型、といった異なるデータ型の要素は比較することができないため、max/minは使用できません。

set_num = {1, 20, "集合"}    ### int型の要素とstr型の要素が混ざっている

print(max(set_num))          
print(min(set_num))          
C:\Python> python 9-3_4.py
Traceback (most recent call last):
File “9-3.py”, line 3, in <module>
print(max(set_num))
TypeError: ‘>’ not supported between instances of ‘str’ and ‘int’

要素を並び替える

セットが持つ要素には順序がないことは、以前の記事で説明しました。
そもそも順序がないので、並び替えのためのメソッドはセットには用意されていません。
ただし、組み込み関数の sorted() を使用することで、要素を並び替えることができます。
その際、関数の戻り値として取得できるのは、リストになります。

例を見てみましょう。

set_num = {100, 50, 300, 1}
print(set_num)

print("---------------")

set_sort = sorted(set_num)      ### sorted() を使ってセットを昇順に並び替え

print(set_sort)
print(type(set_sort))           ### set_sort のデータ型を確認
C:\Python> python 9-3_5.py
{1, 50, 100, 300}
——————————
[1, 50, 100, 300]

<class ‘list’>

セットをsorted()で並び替え、戻り値をset_sortに代入しました。
set_sortのデータ型をtype()で確認すると、リストであることがわかると思います。

sorted() は与えられたものを並び替えて新しくリストを作るので、元のセットには影響がありません。
また、デフォルトの並び順は昇順です。降順に並び替える場合は、引数reverseをTrueとして与えてあげる
必要があります。

set_num = {100, 50, 300, 1}
print(set_num)

print("---------------")

set_sorted = sorted(set_num, reverse=True)     ### 降順に並び替え

print(set_sorted)
print(type(set_sorted))
C:\Python> python 9-3_6.py
{1, 50, 100, 300}
——————————
[300, 100, 50, 1]

<class ‘list’>


frozenset型について

前回までにご説明したとおり、セット型には追加/削除のためのメソッドが用意されています。
つまり、セット型はミュータブルなオブジェクトです。
ですが、Pythonの集合にはイミュータブルなオブジェクトが用意されています。それがfrozenset型です。

frozenset型は、イミュータブルな集合です。
通常の集合、つまりセット型では add() や remove() などを用いて一度作成したセットに対して
要素の追加や削除を行うことができました。
frozenset型ではそれらのメソッドは一切使えないため、一度作成したあと要素を変更したくない集合を
作成する際に用います。例えばユーザーの属性など、もし作成後に要素が変化することがない集合が必要であれば、
このfrozenset型を使う場合があります。

frozenset型を作成する際は、イテラブルな引数をfrozenset関数に与えて作成します。
では、実際に確認してみましょう。

set_test = set(range(5))          ### セット型を作成
f_set = frozenset(set_test)       ### set_testを元に、frozenset型を作成

print(f_set)
print(type(f_set))                ### データ型を確認
C:\Python> python 9-3_7.py
frozenset({0, 1, 2, 3, 4})
<class ‘frozenset’>

上記のように type() でデータ型を確認すると、frozenset型であることが確認できます。
では、本当にイミュータブルなオブジェクトなのか、add() を試してみましょう。

set_test = set(range(5))          ### セット型を作成
f_set = frozenset(set_test)       ### set_testを元に、frozenset型を作成

f_set.add("test")
C:\Python> python 9-3_8.py
Traceback (most recent call last):
File “9-3.py”, line 4, in <module>
f_set.add(“test”)
AttributeError: ‘frozenset’ object has no attribute ‘add’

エラーが出力されました。セット型とは異なり、frozenset型はそもそもadd()などのメソッドが
用意されていないため、要素の追加/削除などを行うとエラーになります。


まとめ

・セット型で使えるメソッドとして、len()、max()、min()、sorted()などがある
・frozenset型は、あとから要素を追加/削除などができないイミュータブルな集合オブジェクト


確認問題

以下の選択肢の中で、正しいものを全て選びましょう。

1.sorted() は、set型で定義されているメソッドである。
2.set型もリスト等と同じようにイテラブルなオブジェクトである。
3.frozenset型は、要素の追加削除を行うことができない。
4.frozenset型のオブジェクトは、set型の要素に含めることができる。

答えはこちらの記事の最後に!
【Python連載】セットの内包表記


前回の確認問題の回答例

前回の記事はこちら→【Python連載】セット(集合)の特徴と作成

集合の要素の追加/削除を試すプログラムを作ってみました。
基本的には、whileで動作をループさせ、4の終了を選択した際のみbreakでプログラムを終了するようにしています。
また、入力した値をint()で数値に変換、その際にtry-except文で数字に変換できない文字列などが入力された際に
その旨を画面に出力できるようにしました。

おおまかなフローを図にしました。(エラー処理などは図が細かくなるので省いています。)

print("要素の追加/削除を試してみましょう。")
set_test = set()

while True:
    print("どの処理を行いますか?番号を入力してください。")
    print("1.追加/2.削除/3.表示/4.終了")
    
    try:
        id = int(input("どの処理を行う?:"))

        if id == 1:
            value = input("追加する値を入力してください:")
            set_test.add(value)

            print(value + "を追加します")
            print("--------------------")

        elif id == 2:
            value = input("削除する値を入力してください:")

            try:
                set_test.remove(value)
                print(value + "を削除します")

            except:
                print(value + "は存在していません")

            print("--------------------")

        elif id == 3:
            print("現在の要素は以下のとおりです。")

            if len(set_test) == 0:
                print("要素がありません。")
                print("--------------------")

            else:
                print(set_test)
                print("--------------------")

        elif id == 4:
            print("プログラムを終了します。")
            break

        else:
            print("1~4の値を入力してください。")
            print("--------------------")

    except:
        print("数字を入力してください。")
        print("--------------------")

連載目次

独学で学ぶ Pythonプログラミング 連載目次