メソッド:dict.items

メソッド items は、写像対の集合に相当します。

>>> help(dict.items)
Help on method_descriptor:

items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples

これを見て、2つの要素を持つタプル(キー, 値)を列挙したリストが得られるのが分かります。実際に、その動作を確認してみましょう。

>>> ex
{'A': 1, 'C': 3, 'B': 2}
>>> ex.items()
[('A', 1), ('C', 3), ('B', 2)]

ここでは、2つの要素を持つタプル(文字列, 整数)を列挙したリストが得られます。ただし、タプルは重複せずに、順不同となります。

ソースコード:items()

(メソッド dict.items に相当する)メソッド items の定義を含む、ソースコードの断片を次に示します。

# IronPython-1.1.2/Src/IronPython/Runtime/Dict.cs
[PythonType("dict")]
public class Dict : ... IDictionary ... {
...
[PythonName("items")]
public List Items() {
return DictOps.Items(this);
}

メソッド Items では、メソッド DictOps.Items の実引数に、this を指定しています。これは、内部クラス DictOps ですべての操作を実現しているので、それに自身 this の処理を委ねるためです。このとき(Dict のインスタンス)this は、インターフェース IDictionary の規定に従うものとします。さらに、IDictionary を構成する各要素は、ジェネリック構造体 KeyValuePair の規定に従うものとします。
《参照》ジェネリック構造体 KeyValuePair:詳細は、http://msdn.microsoft.com/ja-jp/library/5tbh8a42.aspx を参照してください。

    internal static class DictOps {
...
public static List Items(IDictionary self) {
List ret = List.MakeEmptyList(self.Count);
foreach (KeyValuePair kv in self) {
ret.AddNoLock(Tuple.MakeTuple(kv.Key, kv.Value));
}
return ret;
}

静的メソッド Items では、変数 ret がリターン値を扱うために、空の(必要な領域を確保した)リスト List を保持します。すると、次のような構造が見えてきます。

    List ret = ... self.Count ...    // IDictionary.Count
...
return ret;

プロパティー IDictionary.Count を利用しているのが分かります。
ここでは、どのようにしてリストが得られるか(how)は知らなくても、それを使ってなにをしたいか(what)を理解できれば、十分です。self.Count 個の要素を保持するリストが欲しいときに、List.MakeEmptyList を利用するだけです。

foreach 文

ここには、次に示す典型的な C# のイディオムが記述してあります。

    foreach (... kv in self) {
... kv ...
}

foreach ループでは、IDictionary self を構成する各要素 KeyValuePair kv を順に参照します。

    ret.AddNoLock(Tuple.MakeTuple(
kv.Key, // KeyValuePair.Key
kv.Value)); // KeyValuePair.Value

各要素 kv をもとに生成したタプルを、リスト ret に追加します。
ここでは、どのようにしてタプルが得られるか(how)は知らなくても、それを使ってなにをしたいか(what)を理解できれば、十分です。2つの要素(kv.Key, kv.Value)を持つタプルが欲しいときに、Tuple.MakeTuple を利用するだけです。

事例:dict.items を使って

>>> dirs = dict([(e,type(getattr(dict,e))) for e in dir(dict)])
>>> for k,v in dirs.items():
... if k in ["keys","values","items"]: print k,v
...

keys
items
values

これらはどれも、method_descriptor であるのが分かります。


《ひよ子のきもち♪2008/08/22》