Perhatikan kamus berikut, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
Saya ingin mengembalikan kunci N pertama: pasangan nilai dari d (N <= 4 dalam kasus ini). Metode apa yang paling efisien untuk melakukan ini?
Perhatikan kamus berikut, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
Saya ingin mengembalikan kunci N pertama: pasangan nilai dari d (N <= 4 dalam kasus ini). Metode apa yang paling efisien untuk melakukan ini?
Jawaban:
Tidak ada yang namanya kunci "n pertama" karena a dict tidak ingat kunci mana yang dimasukkan lebih dulu.
Anda bisa mendapatkan setiap pasangan n kunci-nilai meskipun:
n_items = take(n, d.iteritems())
Ini menggunakan implementasi takedari itertoolsresep :
from itertools import islice
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
Lihat itu bekerja secara online: ideone
Pembaruan untuk Python 3.6
n_items = take(n, d.items())
iteritemsharus diganti denganitems untuk orang-orang di Python 3
take()bagian dari basis kode python di mana saja? Atau, apakah ini murni fungsi yang Anda tentukan dalam jawaban Anda di sini? Bertanya seolah-olah itu adalah bagian dari basis kode, saya tidak dapat menemukan / mengimpornya. :)
Cara yang sangat efisien untuk mengambil apa pun adalah dengan menggabungkan pemahaman daftar atau kamus dengan pengirisan. Jika Anda tidak perlu memesan item (Anda hanya ingin n pasang acak), Anda dapat menggunakan pemahaman kamus seperti ini:
# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}
Umumnya pemahaman seperti ini selalu lebih cepat dijalankan daripada pengulangan "untuk x dalam y" yang setara. Selain itu, dengan menggunakan .keys () untuk membuat daftar kunci kamus dan memotong daftar itu, Anda menghindari 'menyentuh' tombol yang tidak perlu saat Anda membuat kamus baru.
Jika Anda tidak memerlukan kunci (hanya nilai), Anda dapat menggunakan pemahaman daftar:
first2vals = [v for v in mydict.values()[:2]]
Jika Anda membutuhkan nilai yang diurutkan berdasarkan kuncinya, itu tidak lebih merepotkan:
first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]
atau jika Anda juga membutuhkan kuncinya:
first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}
S Python dicttidak berurut, jadi tidak ada artinya meminta kunci "N pertama".
The collections.OrderedDictkelas tersedia jika itu yang Anda butuhkan. Anda bisa secara efisien mendapatkan empat elemen pertamanya sebagai
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.islicememungkinkan Anda untuk dengan malas mengambil sepotong elemen dari iterator mana pun. Jika Anda ingin hasilnya dapat digunakan kembali, Anda perlu mengubahnya menjadi daftar atau semacamnya, seperti ini:
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))
Pada dasarnya, ubah tampilan (dict_items) menjadi iterator, lalu lakukan iterasi dengan next ().
Tidak melihatnya di sini. Tidak akan dipesan tetapi yang paling sederhana secara sintaksis jika Anda hanya perlu mengambil beberapa elemen dari kamus.
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]} (saham adalah nama kamus saya)
Untuk mendapatkan elemen N teratas dari kamus python Anda, seseorang dapat menggunakan baris kode berikut:
list(dictionaryName.items())[:N]
Dalam kasus Anda, Anda dapat mengubahnya menjadi:
list(d.items())[:4]
Lihat PEP 0265 tentang pengurutan kamus. Kemudian gunakan kode iterable yang disebutkan di atas.
Jika Anda membutuhkan efisiensi lebih dalam pasangan kunci-nilai yang diurutkan. Gunakan struktur data yang berbeda. Yaitu, yang mempertahankan urutan terurut dan pengaitan nilai kunci.
Misalnya
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)]
di py3, ini akan berhasil
{A:N for (A,N) in [x for x in d.items()][:4]}
{'a': 3, 'b': 2, 'c': 3, 'd': 4}
Ini tergantung pada apa yang 'paling efisien' dalam kasus Anda.
Jika Anda hanya ingin sampel semi-acak dari kamus besar foo, menggunakan foo.iteritems()dan mengambil nilai sebanyak yang Anda butuhkan, ini adalah operasi malas yang menghindari pembuatan daftar eksplisit kunci atau item.
Jika Anda perlu mengurutkan kunci terlebih dahulu, tidak ada cara lain untuk menggunakan sesuatu seperti keys = foo.keys(); keys.sort()atau sorted(foo.iterkeys()), Anda harus membuat daftar kunci yang eksplisit. Kemudian iris atau ulangi melalui N pertama keys.
BTW mengapa Anda peduli dengan cara 'efisien'? Apakah Anda membuat profil program Anda? Jika tidak, gunakan cara yang jelas dan mudah dipahami terlebih dahulu. Kemungkinannya akan berhasil dengan baik tanpa menjadi hambatan.
Anda dapat melakukan pendekatan ini dengan berbagai cara. Jika pesanan penting, Anda dapat melakukan ini:
for key in sorted(d.keys()):
item = d.pop(key)
Jika pesanan bukan masalah, Anda dapat melakukan ini:
for i in range(4):
item = d.popitem()
valuebukan itemuntuk kejelasan.
Dictionary tidak memiliki urutan, jadi sebelum memilih pasangan nilai kunci N teratas, mari kita lakukan pengurutan.
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
Sekarang kita dapat melakukan pengambilan elemen 'N' teratas :, menggunakan struktur metode seperti ini:
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
untuk mendapatkan 2 elemen teratas, cukup gunakan struktur ini:
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)
pertimbangkan sebuah dikt
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
from itertools import islice
n = 3
list(islice(d.items(),n))
islice akan melakukan triknya :) semoga bisa membantu!
Ini mungkin tidak terlalu elegan, tetapi berhasil untuk saya:
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
Saya telah mencoba beberapa jawaban di atas dan mencatat bahwa beberapa di antaranya bergantung pada versi dan tidak berfungsi di versi 3.7.
Saya juga mencatat bahwa sejak 3.6 semua kamus diurutkan berdasarkan urutan penyisipan item.
Meskipun kamus diurutkan sejak 3.6, beberapa pernyataan yang Anda harapkan bisa bekerja dengan struktur yang teratur sepertinya tidak berfungsi.
Jawaban atas pertanyaan OP yang paling cocok untuk saya.
itr = iter(dic.items())
lst = [next(itr) for i in range(3)]
lst = list(d.items())[:N]
def GetNFirstItems(self):
self.dict = {f'Item{i + 1}': round(uniform(20.40, 50.50), 2) for i in range(10)}#Example Dict
self.get_items = int(input())
for self.index,self.item in zip(range(len(self.dict)),self.dict.items()):
if self.index==self.get_items:
break
else:
print(self.item,",",end="")
Pendekatan yang tidak biasa, karena memberikan kompleksitas waktu O (N) yang intens.
list(d.items())[:4]. list () adalah implementasi yang mendasari banyak jawaban.