次で終わる既存の関数があります。d
は辞書です。
return d.iteritems()
指定された辞書のソートされていないイテレータを返します。keyでソートされたアイテムを通過するイテレータを返したいと思います。それ、どうやったら出来るの?
次で終わる既存の関数があります。d
は辞書です。
return d.iteritems()
指定された辞書のソートされていないイテレータを返します。keyでソートされたアイテムを通過するイテレータを返したいと思います。それ、どうやったら出来るの?
これはあまり広範囲にテストされていませんが、Python2.5.2で動作します。
>>> d = {"x":2, "h":15, "a":2222}
>>> it = iter(sorted(d.iteritems()))
>>> it.next()
('a', 2222)
>>> it.next()
('h', 15)
>>> it.next()
('x', 2)
>>>
イテレータの代わりに行うことに慣れている場合for key, value in d.iteritems(): ...
、これは上記のソリューションで引き続き機能します
>>> d = {"x":2, "h":15, "a":2222}
>>> for key, value in sorted(d.iteritems()):
>>> print(key, value)
('a', 2222)
('h', 15)
('x', 2)
>>>
Python 3.xでは、d.items()
代わりにを使用d.iteritems()
してイテレータを返します。
sorted()
関数を使用します。
return sorted(dict.iteritems())
sorted()
リストを返すため、ソートされた結果に対して実際のイテレータが必要な場合は、次を使用します。
return iter(sorted(dict.iteritems()))
dictのキーはハッシュテーブルに格納されるため、「自然な順序」、つまり疑似ランダムになります。その他の順序付けは、dictの消費者の概念です。
sort()は、dictではなく、常にリストを返します。dict.items()(タプルのリストを生成する)を渡すと、ループで使用できるタプルのリスト[(k1、v1)、(k2、v2)、...]が返されます。口述に非常によく似ていますが、とにかく口述ではありません!
foo = {
'a': 1,
'b': 2,
'c': 3,
}
print foo
>>> {'a': 1, 'c': 3, 'b': 2}
print foo.items()
>>> [('a', 1), ('c', 3), ('b', 2)]
print sorted(foo.items())
>>> [('a', 1), ('b', 2), ('c', 3)]
以下はループ内のdictのように感じますが、そうではありません。k、vにアンパックされているタプルのリストです。
for k,v in sorted(foo.items()):
print k, v
ほぼ同等:
for k in sorted(foo.keys()):
print k, foo[k]
グレッグの答えは正しいです。Python 3.0 では、次のことを行う必要があることに注意してください。
sorted(dict.items())
iteritems
なくなるように。
OrderedDict
Python 2.7 でも使用できるようになりました。
>>> from collections import OrderedDict
>>> d = OrderedDict([('first', 1),
... ('second', 2),
... ('third', 3)])
>>> d.items()
[('first', 1), ('second', 2), ('third', 3)]
ここには、バージョン 2.7 とOrderedDict APIの新機能ページがあります。
一般に、次のようにdictを並べ替えることができます。
for k in sorted(d):
print k, d[k]
質問の特定のケースでは、d.iteritems()の「ドロップイン置換」を使用して、次のような関数を追加します。
def sortdict(d, **opts):
# **opts so any currently supported sorted() options can be passed
for k in sorted(d, **opts):
yield k, d[k]
したがって、終了行はから変更されます
return dict.iteritems()
に
return sortdict(dict)
また
return sortdict(dict, reverse = True)
>>> import heapq
>>> d = {"c": 2, "b": 9, "a": 4, "d": 8}
>>> def iter_sorted(d):
keys = list(d)
heapq.heapify(keys) # Transforms to heap in O(N) time
while keys:
k = heapq.heappop(keys) # takes O(log n) time
yield (k, d[k])
>>> i = iter_sorted(d)
>>> for x in i:
print x
('a', 4)
('b', 9)
('c', 2)
('d', 8)
このメソッドにはまだ O(N log N) の並べ替えがありますが、短い線形 heapify の後、並べ替えられた順序で項目が生成されるため、常にリスト全体が必要ではない場合に理論的に効率的になります。
キーの順序ではなく、アイテムが挿入された順序で並べ替えたい場合は、Python のcollections.OrderedDictを参照する必要があります。(Python 3 のみ)
sorted はリストを返すため、それを反復しようとするとエラーになりますが、辞書を注文できないため、リストを処理する必要があります。
コードのより大きなコンテキストが何であるかはわかりませんが、結果のリストに反復子を追加してみてください。こんな感じかな?:
return iter(sorted(dict.iteritems()))
もちろん、sorted によって dict がタプルのリストに変換されるため、タプルが返されます。
例: あなたの口述があったとしましょう:
{'a':1,'c':3,'b':2}
sorted はそれをリストに変えます:
[('a',1),('b',2),('c',3)]
そのため、実際にリストを反復処理すると (この例では) 文字列と整数で構成されるタプルが返されますが、少なくともそれを反復処理することはできます。
CPython 2.x を使用していて、大きなディクショナリ mydict があると仮定すると、sorted(mydict) の使用は遅くなります。
その場合、C での C 実装を含む、ordereddict パッケージを確認することをお勧めしsorteddict
ます。特に、辞書の有効期間のさまざまな段階 (つまり、要素の数) でキーの並べ替えられたリストを複数回調べる必要がある場合。