情報学部 菅沼ホーム 目次 索引

複合データ

  ここは,複数のデータの集まりからなるデータ(複合データ)について説明します.

  1. シーケンス型

      シーケンス型は,有限の順序集合を表現します.要素の値等を変更できない(イミュータブル)シーケンス型として文字列型タプル型tuple 型),bytes 型が存在します.また,変更可能な(ミュータブル)シーケンス型として,リスト型list 型),range 型bytearray 型が存在します.なお,先に述べた複素数も,変更不可能なシーケンス型の一種とみなすことができますが,ここでは説明を省略します.

    1. 要素の参照(添え字とスライス)

        シーケンス型のデータを参照する基本的な方法は,C/C++ における配列と同様,添え字です.ただし,Python においては,負の添え字も使用することができます(このような機能,必要?).ここでは,文字列,
      test = "Suganuma"				
      を例として,説明していきます.正の添え字を使用する場合,先頭の文字に対応する添え字は 0,最後の文字に対応する添え字が (n-1) (文字数が n の場合)になります.また,負の添え字を使用する場合は,最後の文字に対応する添え字が -1,先頭の文字に対応する添え字が -n (文字数が n の場合)になります.上に示した文字列に対して,その添え字は,
      +---+---+---+---+---+---+---+---+
      | S | u | g | a | n | u | m | a |
      +---+---+---+---+---+---+---+---+
        0   1   2   3   4   5   6   7
       -8  -7  -6  -5  -4  -3  -2  -1				
      となり,
      >>> test = "Suganuma"
      >>> test[0]
      'S'
      >>> test[-2]
      'm'				
      のような結果が得られます.

        Python においては,スライスslice )という表現を使用し,部分文字列を指定することが可能です(このような機能,必要?).スライスは,
      [m1:m2[:m3]]				
      のように記述され,添え字 m が m1 <= m < m2 である部分文字列を指定することができます.開始インデックス m1 を省略すると 0,終了インデックスを省略すると文字列の長さと見なされます.なお,m3 を入力すると,m1 から m2 までの m3 個ごとの要素という意味になります.この結果,上に示した例に対しては,以下に示すような結果が得られます.
      >>> test = "Suganuma"
      >>> test[0:4]
      'Suga'
      >>> test[:4]
      'Suga'
      >>> test[4:]
      'numa'
      >>> test[4:-1]
      'num'
      >>> test[0:8:2]
      'Sgnm'
      				
        C/C++ には,負の添え字やスライスに対応する参照方法がありません.特に,スライスに関しては後に述べる for 文などの繰り返し文を使用する必要があり,例えば,以下に示すように記述する必要があります.上で述べた参照方法だけを採り上げても,Python のように,プログラムの記述を簡単にするためだけを目的に,多くの規則を導入する方が良いのか,疑問を感じます.少なくとも,Python に対する知識がない人には,理解しにくくなることは確かです.なお,以下に示すプログラムにおいて,cout は出力を行い,strlen や length() は文字列の長さを返す関数です.
      				// 配列を使用
      char test1[] = "Suganuma";
      cout << test1[0] << endl;   // test[0] に対応
      cout << test1[strlen(test1)-2] << endl;   // test[-2] に対応
      for (int i1 = 0; i1 < 8; i1 += 2)   // test[0:8:2] に対応
      	cout << test1[i1];
      cout << endl;
      				// string クラスを使用
      string test2 = "Suganuma";
      cout << test2[0] << endl;   // test[0] に対応
      cout << test2[test2.length()-2] << endl;   // test[-2] に対応
      for (int i1 = 0; i1 < 8; i1 += 2)   // test[0:8:2] に対応
      	cout << test2[i1];
      cout << endl;
      				

    2. シーケンス型に共通の演算

        以下に示す演算は,ほとんどの変更不可能及び変更可能なシーケンス型でサポートされています.同じ型のシーケンス同士に対しては,比較もサポートしています.等しいとされるためには,すべての要素が等しく,両シーケンスの型も長さも等しくなければなりません.C++ においても,C++ 標準ライブラリ内の各クラスのメンバー関数やアルゴリズムに,似た機能を持つ関数が存在します.適宜,string クラスを利用して,C++ に対するプログラム例も併記していきます.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

        • + : 結合
        • * : 繰り返し(このような機能,必要?
        • count : 出現回数
        • in : 包含関係
        • index : 検索
        • len : 長さ(組み込み関数)
        • max : 最大(組み込み関数)
        • min : 最小(組み込み関数)
        • not in : 包含関係でない

    3. 変更不可能なシーケンス

      1. 文字列型
          文字列str オブジェクトであり,一重引用符「 ' 」または二重引用符「 " 」で囲み,結果はどちらも同じ文字列になります.また,一重引用符または二重引用符を 3 つ続ける(「 ''' 」または「 """ 」)ことによって,複数行にわたる文字列も表現できます.文字列リテラルに関しては,「文字列およびバイト列リテラル」も参考にしてください.文字列を修正したい場合は,修正した内容を持つ新しい文字列を生成することによって対応可能です.

          C++ における配列を使用した文字列や C++ 標準ライブラリ内の string クラスと似ていますが,配列や string クラスにおいては,下のプログラム例に示すように,文字列の修正も可能です.ただし,const 指定を行えば,修正不可能になります.配列を使用して文字列を表した場合は C/C++ の標準関数,string クラスを使用して文字列を表した場合はそのメンバー関数やアルゴリズムを使用することによって,以下に示す関数と同等の処理が可能になります.なお,string クラスを使用した場合は,+ 演算子による文字列の結合,比較演算子や等値演算子による文字列の比較なども可能になります.
        			// 配列の利用
        char x[] = "abcd";   // const char x[] = "abcd"; とすれば修正不可能
        x[1]     = 'x';   // 修正もOK
        cout << x << endl;   // axcd を出力
        			// String クラスの利用
        string y = "abcd";   // const string y = "abcd"; とすれば y の修正は不可能
        string z = y + "xyz";   // + 演算子による結合もOK
        z[0]     = 'A';   // 修正もOK
        cout << z << endl;   // Abcdxyz を出力					
          文字列に対しては,先に述べたシーケンス型に共通の演算全てに加え,以下に述べるメソッドを使用することができます.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • format : 書式化
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdecimal : 十進数字か?
          • isdigit : 数字か?
          • isidentifier : 識別子として有効か?
          • islower : 小文字か?
          • isnumeric : 数を表す文字か?
          • isprintable : 印刷可能か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

      2. タプル型( tuple 型)

          タプルtuple )の要素は任意の Python オブジェクトです.タプルは,以下に示すような方法で生成することができます.なお,タプルを生成するのはカンマであり,問題がなければ,丸括弧 () を省略してかまいません.以下に示すように,C/C++ における const 指定(修正不可能な定数)した配列に似ていますが,タプルでは,異なる型のオブジェクトを要素として持つことができます.C++ には,異なる要素を記憶可能な tuple クラス が存在しますが,Python におけるタプルとはかなり異なったものです.リスト型集合型辞書型なども同様ですが,「異なる型のオブジェクトを要素として持つことができる」という仕様には疑問を感じます.誤りの原因となりやすく,避けた方が良いと思います.
        const int x[] = {10, 20, 30};
        tuple<int, string, double, string> t(1, "aaa", 3.14, "bbb");					

        • 空のタプル  (),または,組み込み関数 tuple() の使用
          >>> ()
          ()
          >>> tuple()
          ()						

        • 単要素のタプル  (a,),または,組み込み関数 tuple(単要素の iterable) の使用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下に示す 3 番目の例では,リストを使用している.
          >>> ("abc",)
          ('abc',)
          >>> "abc",
          ('abc',)
          >>> tuple(["abc"])
          ('abc',)						

        • 一般的なタプル  (a, b, ・・・),または,組み込み関数 tuple(iterable) の使用.tuple() は,iterable の項目と同じ項目で同じ順のタプルを構築する.最後の 3 行のように,タプルの要素をタプルとして,2 次元配列に対応したタプルを生成することも可能である.
          >>> ("abc", 10, "xxx")
          ('abc', 10, 'xxx')
          >>> "abc",10,"xxx",
          ('abc', 10, 'xxx')
          >>> tuple(["abc", 10, complex(1,3)])
          ('abc', 10, (1+3j))
          >>> tuple("abc")
          ('a', 'b', 'c')
          >>> a = ((1, 2, 3), (10, 20, 30))
          >>> a[0][1]
          2						

      3. bytes 型

          bytes オブジェクトの要素は,8-bit,1 バイトであり,0 <= x < 256 の範囲の整数で表現されます.以下に示すような方法で生成することができます.以下に示すように,C/C++ においては,半角文字だけを対象とし,const 指定(修正不可能な定数)された char 型の配列C++ 標準ライブラリ内の string クラスに似ています.
        const char x[] = "abcd";
        const string x = "abcd";					

        • リテラルの利用  文字列リテラルと同様の方法で生成可能.ただし,文字列の前に b を付加する必要がある.
          >>> b"abc"
          b'abc'						

        • 組み込み関数 bytes() を使用し,指定された長さの 0 で埋められた bytes オブジェクトを生成
          >>> bytes(5)
          b'\x00\x00\x00\x00\x00'						

        • 組み込み関数 bytes() と整数を要素とする iterable の利用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下の例では,rangeリストを使用している.
          >>> bytes(range(5))
          b'\x00\x01\x02\x03\x04'
          >>> bytes([1, 2, 3, 4, 5])
          b'\x01\x02\x03\x04\x05'						

          bytes に対しては,先に述べたシーケンス型に共通の演算全てに加え,以下に述べるメソッドを使用することができます.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • decode : bytes を文字列に変換
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • fromhex : 16 進表記文字列を bytes に変換
          • hex : bytes を 16 進表記に変換
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdigit : 数字か?
          • islower : 小文字か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

    4. 変更可能なシーケンス

      1. 変更可能シーケンスに固有の演算

          以下に示す演算は,ほとんどの変更可能なシーケンスで使用可能です.ここで,s は変更可能なシーケンス型のオブジェクト,t は任意のイテラブルオブジェクト,x は s に課せられた型と値の条件を満たす任意のオブジェクトです.ここで,iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

          • s *= n : n 回反復(このような機能,必要?
          • s[i] = x : 代入
          • s[i:j] = t : 代入(このような機能,必要?
          • s[i:j:k] = t : 代入(このような機能,必要?
          • del s[i:j] : 削除(このような機能,必要?
          • del s[i:j:k] : 削除(このような機能,必要?
          • append : 追加
          • clear : 全削除
          • copy : 浅いコピー
          • extend : 追加
          • insert : 挿入
          • pop : 取り出して削除
          • remove : 削除
          • reverse : 順序の逆転

          ここにおいても,記述の簡単さだけを目指して,あまり特殊な機能は使用しない方が良いと思います.特に,Python に対する知識のない人にとっては,理解しがたいプログラムになってしまいます.参考のため,いくつかの例に対しては,C++ 標準ライブラリ内の vector クラスを使用した C++ のプログラム例を載せておきます(出力結果は同じであるため除く).その際,出力文「 cout << 」に対しては,以下に示すように,<< 演算子のオーバーロードがされているものとします.
        ostream& operator << (ostream& stream, vector<int> &s)
        {
        	if (s.empty())
        		stream << "[]\n";
        	else {
        		stream << "[";
        		for (unsigned int i1 = 0; i1 < s.size(); i1++) {
        			stream << s[i1];
        			if (i1 < s.size()-1)
        				stream << ", ";
        		}
        		stream << "]\n";
        	}
        	return stream;
        }
        					

      2. リスト型( list 型)

          リストlist )は変更可能なシーケンスであり,一般的に同種の項目の集まりを格納するために使われます.C++ における C++ 標準ライブラリ内の vector クラスと似ていますが,vector とは異なり,異なる型のオブジェクトを要素として持つことができます.タプル型集合型辞書型なども同様ですが,「異なる型のオブジェクトを要素として持つことができる」という仕様には疑問を感じます.誤りの原因となりやすく,避けた方が良いと思います.リストの生成には,以下に示すように,いくつかの方法があります.

        • [],または,組み込み関数 list() の使用  空のリスト
          >>> []
          []
          >>> list()
          []						

        • 角括弧とカンマの使用
          >>> [1, 2, 3]
          [1, 2, 3]
          >>> a = [1, 2, 3]
          >>> a[0]
          1
          >>> b = [[1, 2, 3], [4, 5, 6]]
          >>> b[1][0]
          4						

        • list(iterable) の使用( iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクト)
          >>> list("abcd")
          ['a', 'b', 'c', 'd']
          >>> list(("a", "b", "c", "d"))
          ['a', 'b', 'c', 'd']						

        • リスト内包表記( [x for x in iterable] など)の使用
          >>> [x for x in "abcd"]
          ['a', 'b', 'c', 'd']						

          リストに対しては,先に述べた共通のシーケンス演算全てに加え,以下に述べるメソッドを使用することができます.

        • sort(*, key=None, reverse=None) : 項目間の < 比較のみを用いてリストをソート.2 つの引数をキーワード引数としてのみ渡せる.key は 1 引数をとる関数を指定し,リストのそれぞれの要素から比較キーを取り出すのに使用(例えば,key=str.lower).また,reverse は,ブール値であり,True に設定された場合,リストの要素は各比較が反転したように並び替えられる. >>> s = [1, 4, 3, 2, 5] >>> s.sort() >>> s [1, 2, 3, 4, 5] >>> s.sort(reverse=True) >>> s [5, 4, 3, 2, 1]

          C++ の場合

          vector<int> s;
          s.push_back(1);
          s.push_back(4);
          s.push_back(3);
          s.push_back(2);
          s.push_back(5);
          sort(s.begin(), s.end(), less<int>());
          cout << s;
          sort(s.begin(), s.end(), greater<int>());
          cout << s;						

      3. range 型

          range 型は,数の変更可能なシーケンスを表し,一般に for ループにおいて,特定の回数のループを実行するために使われます.range 型のオブジェクトは,組み込み関数,

        class range(stop)
        class range(start, stop[, step])

        によって生成可能です.ただし,start,stop,step 共に,整数である必要があります.step 引数が省略された場合のデフォルト値は 1,start 引数が省略された場合のデフォルト値は 0 です.各引数の値は,各々,インスタンス変数 start,stop,step によって知ることができます(変更不可能).なお,C/C++ には,直接対応する機能は存在しません.しかし,繰り返し文によって容易に実現可能です.
        >>> list(range(1, 10, 2))
        [1, 3, 5, 7, 9]
        >>> list(range(10, -3, -1))
        [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2]
        >>> r = range(1, 10, 2)
        >>> r.step
        2
        >>> r[2]
        5					

        C++ の場合

        vector<int> s1, s2;
        for (int i1 = 1; i1 < 10; i1 += 2)
        	s1.push_back(i1);
        cout << s1;
        for (int i1 = 10; i1 > -3; i1--)
        	s2.push_back(i1);
        cout << s2;					

      4. bytearray 型

          bytearray オブジェクトの要素は,8-bit,1 バイトであり,0 <= x < 256 の範囲の整数で表現されます.C++ の C++ 標準ライブラリ内の string クラスに似ています(半角文字だけを対象とした場合).bytearray に専用のリテラル構文はありませんので,組み込み関数を使って作成します.

        • 組み込み関数 bytearray() を使用し,空のオブジェクトを作成
          >>> bytearray()
          bytearray(b'')						

        • 組み込み関数 bytearray() を使用し,指定された長さの 0 で埋められた bytearray オブジェクトの生成
          >>> bytearray(5)
          bytearray(b'\x00\x00\x00\x00\x00')						

        • 組み込み関数 bytearray() と整数を要素とする iterable の利用.iterableイテラブル)とは,構成要素を一度に一つずつ返すことができるオブジェクトである.下の例では,range を使用している.
          >>> bytearray(range(5))
          bytearray(b'\x00\x01\x02\x03\x04')
          >>> bytearray([1, 2, 3, 4, 5])
          bytearray(b'\x01\x02\x03\x04\x05')						

        • 組み込み関数 bytearray() を使用し,既存のバイナリデータから生成
          >>> bytearray(b"abc")
          bytearray(b'abc')						

          bytearray に対しては,先に述べた共通のシーケンス演算全てに加え,以下に述べるメソッドを使用することができます.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

          • capitalize : 最初の文字だけを大文字に変換
          • center : 中央揃い
          • count : 出現回数
          • decode : bytearray を文字列に変換
          • endswith : 指定した文字で終わっているか?
          • expandtabs : タブを半角スペースに変換
          • find : 文字列の探索
          • fromhex : 16 進表記文字列を bytearray に変換
          • hex : bytearray を 16 進表記に変換
          • index : 文字列の探索
          • isalnum : 英数字か?
          • isalpha : 英字か?
          • isdigit : 数字か?
          • islower : 小文字か?
          • isspace : スペースか?
          • istitle : タイトルケースか?
          • isupper : 大文字か?
          • join : 文字列の結合
          • ljust : 左揃え
          • lower : 小文字に変換
          • lstrip : 先頭文字の削除
          • partition : 文字列を前から見た最初の区切り文字で 3 分割
          • replace : 文字列の置換
          • rfind : 文字列の後方からの探索
          • rindex : 文字列の後方からの探索
          • rjust : 右揃え
          • rpartition : 文字列を後ろから見た最初の区切り文字で 3 分割
          • rsplit : 区切り文字で文字列を分割
          • rstrip : 末尾の文字の削除
          • split : 区切り文字で文字列を分割
          • splitlines : 文字列を改行で分割
          • startswith : 指定した文字で始まっているか?
          • strip : 先頭及び末尾の文字を削除
          • swapcase : 大文字と小文字の変換
          • title : タイトルケースに変換
          • upper : 大文字に変換
          • zfill : 0 で左詰

  2. 集合型( set 型)

      set オブジェクトは,ハッシュ可能な(変更不可能な)オブジェクトの順序のない集まりであり,数学における集合に相当します.従って,ある要素が含まれる,要素の数等に相当する演算は可能ですが,添え字,スライスなど,シーケンス型に対して使用されるような操作は不可能です.C++ の C++ 標準ライブラリ内の set クラスunordered_set クラスと似ていますが,これらのクラスとは異なり,異なる型のオブジェクトを要素として持つことができます.タプル型リスト型辞書型なども同様ですが,「異なる型のオブジェクトを要素として持つことができる」という仕様には疑問を感じます.誤りの原因となりやすく,避けた方が良いと思います.なお,C++ における set クラスでは,データが入力されるたびに,自動的にソートされます.

      ハッシュ可能なオブジェクトとは,そのオブジェクトが存在する期間中変わらないハッシュ値を持ち,他のオブジェクトと比較ができるオブジェクトです.ハッシュ可能なオブジェクトは辞書キーや集合のメンバーとして使えます.辞書や集合のデータ構造は内部でハッシュ値を使っているからです.Python の変更不可能なオブジェクトはハッシュ可能ですが,変更可能なオブジェクト,例えばリスト辞書はハッシュ不可能です.

      set および frozenset という 2 種類の集合型が存在します.set は変更可能な集合型であり,要素の追加や削除が可能です.変更可能なため,ハッシュ値を持たず,辞書のキーや他の集合の要素として用いることができません.一方,frozenset 型は変更不可能であり,ハッシュ可能です.作成後に内容を改変できないため,辞書のキーや他の集合の要素として用いることができます.

      set は,要素を波括弧中にカンマで区切って列挙する(空の set は波括弧だけ)ことによって生成できます.また,set および frozenset は,組み込み関数,

    class set([iterable])
    class frozenset([iterable])

    を使用して生成することも可能です.iterable が指定されないと,空の集合が作成されます.iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.
    >>> {}   # 空の set
    {}
    >>> {1, 2, 3}
    {1, 2, 3}
    >>> {1, 2, 3, 3, 3}   # 同じ要素は含まない
    {1, 2, 3}
    >>> set([1, 2, 3])
    {1, 2, 3}
    >>> frozenset([1, 2, 3])
    frozenset({1, 2, 3})			
      set および frozenset のオブジェクトに対しては,以下に示す操作が可能です.なお,union(),intersection(),difference(),symmetric_difference(),issubset(),issuperset() メソッドは,任意のイテラブルを引数(set1,set2,・・・)として受け付けますが,それらのメソッドを演算子を使用して実現した場合は,引数は集合でなくてはなりません.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

      ここにおいても,記述の簡単さだけを目指して,あまり特殊な機能は使用しない方が良いと思います.特に,Python に対する知識のない人にとっては,理解しがたいプログラムになってしまいます.参考のため,いくつかの例に対しては,C++ 標準ライブラリ内の set クラスを使用した C++ のプログラム例を載せておきます(出力結果は同じであるため除く).ハッシュを使用するといった点では,unordered_set クラスの方が似ていますが,ソート関係のアルゴリズムを使用し,Python の場合と似たプログラムを記述するため,要素が自動的にソートされる set クラスを使用します.その際,出力文「 cout << 」に対しては,以下に示すように,<< 演算子のオーバーロードがされているものとします.
    ostream& operator << (ostream& stream, set<int> &s)
    {
    	if (s.empty())
    		stream << "{}\n";
    	else {
    		stream << "{";
    		set<int>::iterator it;
    		unsigned int k = 0;
    		for (it = s.begin(); it != s.end(); it++) {
    			stream << *it;
    			if (k < s.size()-1)
    				stream << ", ";
    			k++;
    		}
    		stream << "}\n";
    	}
    	return stream;
    }
    			

      以下に示す演算は set には適用できますが,変更不可能である frozenset のオブジェクトには適用できません.なお,update(),intersection_update(),difference_update(),および,symmetric_difference_update() メソッドは,任意のイテラブルを引数として設定できますが,それらのメソッドを演算子を使用して実現した場合は,引数は集合でなくてはなりません.また,remove(),および,discard() メソッドの引数は集合でも構いません.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

  3. マッピング型(辞書型)

      マッピングmapping )オブジェクトは.ハッシュ可能な値であるキーと任意のオブジェクトのペアから構成されます.現在,標準のマッピング型は辞書dictionary )だけです.辞書のキーは,ほぼ,任意の値です.ただし,ハッシュ可能でない値,つまり,リストや辞書など変更可能な型はキーとして使用できません.C++ の C++ 標準ライブラリ内の map クラスunordered_map クラス と似ていますが,これらのクラスとは異なり,異なる型のオブジェクトを要素として持つことができます.タプル型リスト型集合型なども同様ですが,「異なる型のオブジェクトを要素として持つことができる」という仕様には疑問を感じます.誤りの原因となりやすく,避けた方が良いと思います.なお,C++ における map クラスでは,データが入力されるたびに,自動的にソートされます.

      辞書は,key : value 対をカンマで区切り,波括弧「 { } 」でくくることで作成できます.また,組み込み関数,

    class dict(**kwarg)
    class dict(mapping, **kwarg)
    class dict(iterable, **kwarg)

    を使用することによっても可能です.iterable のそれぞれの要素自身は,2 個のオブジェクトを持つイテラブルでなければなりません.それぞれの要素の最初のオブジェクトは新しい辞書のキーになり,2 番目のオブジェクトはそれに対応する値になります.同一のキーが 2 回以上現れた場合は,そのキーの最後の値が新しい辞書での対応する値になります.iterableイテラブル)とは,リストタプルrange など,構成要素を一度に一つずつ返すことができるオブジェクトです.

      キーワード引数 kwarg が与えられた場合,キーワード引数とその値が mapping または iterable から作成された辞書に追加されます.既に存在しているキーが追加された場合,キーワード引数の値は位置引数の値を置き換えます.

      以下に示す例は,空の辞書を生成する場合を除き,すべて同じ辞書を生成します.
    >>> d = {}   # 空の辞書
    >>> d = dict()   # 空の辞書
    >>> d = {"aaa" : 10, "bbb" : 20, "ccc" : 30}   # key:value 対と波括弧の利用
    >>> d = dict(aaa = 10, bbb = 20, ccc = 30)   # kwarg の利用
    >>> d = dict({"aaa" : 10, "bbb" : 20, "ccc" : 30})   # mapping の利用
    >>> d = dict({"aaa" : 10, "bbb" : 20}, ccc = 30)   # mapping と kwarg
    >>> d = dict([("aaa" , 10), ("bbb" , 20), ("ccc" , 30)])   # iterable の利用			
      辞書型のオブジェクトに対しては,以下に示す操作が可能です.なお,すぐ下に示すのは,それ以降に詳細説明を行っている項目の目次になっています.ここをクリックすると,詳細説明の表示/非表示が切り替わります.

      • key in dic : key を持っているか?
      • key not in dic : key を持っていないか?
      • dic[key] : key に対応する値
      • dic[key] = value : key に対応する値を value に設定
      • clear : 全項目を削除
      • copy : 浅いコピー
      • del dic[key] : key で示される項目を削除
      • fromkeys : 新しい辞書を作成
      • get : キーに対応する値
      • items : 項目のビュー
      • iter : キーに関するイテレータ
      • kyes : キーのビュー
      • len : 項目数
      • pop : キーに対応する項目の取り出しと削除
      • popitem : 任意の項目を削除
      • setdefault : キーに対応する項目の取り出しまたは追加
      • update : 辞書の更新
      • values : 値のビュー

      ここにおいても,記述の簡単さだけを目指して,あまり特殊な機能は使用しない方が良いと思います.特に,Python に対する知識のない人にとっては,理解しがたいプログラムになってしまいます.参考のため,いくつかの例に対しては,C++ 標準ライブラリ内の unordered_map クラスを使用した C++ のプログラム例を載せておきます(出力結果は同じであるため除く).その際,出力文「 cout << 」に対しては,以下に示すように,<< 演算子のオーバーロードがされているものとします.
    ostream& operator << (ostream& stream, unordered_map<string, int> &m)
    {
    	if (m.empty())
    		stream << "{}\n";
    	else {
    		unordered_map<string, int>::iterator it;
    		unsigned int k = 0;
    		stream << "{";
    		for (it = m.begin(); it != m.end(); it++) {
    			stream << (*it).first << " : " << (*it).second;
    			if (k < m.size()-1)
    				stream << ", ";
    			k++;
    		}
    		stream << "}\n";
    	}
    	return stream;
    }
    			

情報学部 菅沼ホーム 目次 索引