次の辞書dを考えてみます。
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
最初のN個のキーと値のペアをdから返したい(この場合はN <= 4)。これを行う最も効率的な方法は何ですか?
次の辞書dを考えてみます。
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
最初のN個のキーと値のペアをdから返したい(この場合はN <= 4)。これを行う最も効率的な方法は何ですか?
回答:
a dict
は最初に挿入されたキーを覚えていないので、「最初のn」キーはありません。
ただし、 n個のキーと値のペアを取得できます。
n_items = take(n, d.iteritems())
これは、レシピのtake
from の実装を使用しitertools
ます。
from itertools import islice
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
オンラインで動作することを確認してください:ideone
Python 3.6の更新
n_items = take(n, d.items())
iteritems
代わるべきだと思いますitems
take()
-Pythonコードベースの一部はどこにありますか?それとも、ここで回答で定義した純粋な関数ですか?それがコードベースの一部であるかのように尋ねると、それを見つけたりインポートしたりできません。:)
何かを検索する非常に効率的な方法は、リストまたは辞書の内包表記とスライスを組み合わせることです。アイテムを注文する必要がない場合(n個のランダムなペアが必要なだけ)、次のような辞書内包を使用できます。
# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}
一般に、このような理解は、同等の「for x in y」ループよりも常に実行が高速です。また、.keys()を使用してディクショナリキーのリストを作成し、そのリストをスライスすることで、新しいディクショナリを構築するときに不要なキーに「触れる」ことを回避できます。
キー(値のみ)が必要ない場合は、リスト内包表記を使用できます。
first2vals = [v for v in mydict.values()[:2]]
キーに基づいて値をソートする必要がある場合は、それほど問題ではありません。
first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]
または、キーも必要な場合:
first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}
Pythonのdict
は順序付けされていないため、「最初のN」キーを要求しても意味がありません。
それcollections.OrderedDict
が必要な場合は、クラスを利用できます。最初の4つの要素を効率的に取得できます。
import itertools
import collections
d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)
for key, value in x:
print key, value
itertools.islice
イテレータから要素のスライスを遅延して取得できます。結果を再利用可能にしたい場合は、次のようにリストまたは何かに変換する必要があります。
x = list(itertools.islice(d.items(), 0, 4))
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
print(next(iterator))
基本的には、ビュー(dict_items)をイテレータにしてから、next()で繰り返します。
ここでは見ませんでした。辞書からいくつかの要素を取得する必要がある場合は、順序付けはされませんが、構文的には最も単純です。
n = 2
{key:value for key,value in d.items()[0:n]}
TypeError: 'dict_items' object is not subscriptable
{key:value for key,value in stocks.items()[0:n]}
(stocksは私の辞書の名前です)
Python辞書から上位N個の要素を取得するには、次のコード行を使用できます。
list(dictionaryName.items())[:N]
あなたの場合、それを次のように変更できます:
list(d.items())[:4]
PEP 0265を参照辞書のソートを。次に、前述の反復可能なコードを使用します。
ソートされたキーと値のペアでさらに効率が必要な場合。別のデータ構造を使用してください。つまり、ソートされた順序とキーと値の関連付けを維持するものです。
例えば
import bisect
kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))
print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
py3では、これはトリックを行います
{A:N for (A,N) in [x for x in d.items()][:4]}
{'a':3、 'b':2、 'c':3、 'd':4}
これは、あなたのケースで何が「最も効率的」かによって異なります。
巨大な辞書の半ランダムなサンプルが必要なだけで、そこから必要な数の値をfoo
使用foo.iteritems()
して取得する場合、これはキーまたはアイテムの明示的なリストの作成を回避する遅延操作です。
最初にキーをソートする必要がある場合は、keys = foo.keys(); keys.sort()
またはのようなものを使用する方法がないsorted(foo.iterkeys())
ため、キーの明示的なリストを作成する必要があります。次に、最初のNをスライスまたは反復します。keys
ます。
ところで、なぜ「効率的な」方法を気にするのですか?プログラムのプロファイルを作成しましたか?そうでない場合は、最初に明白でわかりやすい方法を使用してください。ボトルネックになることなく、かなりうまくいく可能性があります。
辞書は順序を維持しないため、上位N個のキーと値のペアを選択する前に、並べ替えることができます。
import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values
これで、次のようなメソッド構造を使用して、上位の「N」要素の取得を実行できます。
def return_top(elements,dictionary_element):
'''Takes the dictionary and the 'N' elements needed in return
'''
topers={}
for h,i in enumerate(dictionary_element):
if h<elements:
topers.update({i:dictionary_element[i]})
return topers
上位2つの要素を取得するには、次の構造を使用します。
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)
口述を考える
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
from itertools import islice
n = 3
list(islice(d.items(),n))
isliceはトリックを行います:)それが役に立てば幸いです!
これはあまりエレガントではないかもしれませんが、私にとってはうまくいきます:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
x= 0
for key, val in d.items():
if x == 2:
break
else:
x += 1
# Do something with the first two key-value pairs
上記の回答のいくつかを試してみましたが、それらの一部はバージョンに依存しており、バージョン3.7では機能しないことに注意してください。
また、3.6以降、すべての辞書はアイテムが挿入される順序で並べられていることに注意してください。
辞書は3.6以降で順序付けされていますが、順序付けられた構造で動作すると予想される一部のステートメントは動作しないようです。
私にとって最も効果的なOP質問への回答。
itr = iter(dic.items())
lst = [next(itr) for i in range(3)]
lst = list(d.items())[:N]
list(d.items())[:4]
ます。list()は多くの回答の基礎となる実装です。