Розглянемо наступний словник, 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 у цьому випадку). Який найефективніший метод цього зробити?
Відповіді:
Немає такого поняття "перших n" клавіш, оскільки dict
не пам'ятає, які клавіші були вставлені першими.
Ви можете отримати будь-які n пар ключових значень:
n_items = take(n, d.iteritems())
Це використовує реалізацію take
з 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
на людей на Python 3
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]}
Як правило, таке розуміння завжди проходить швидше, ніж еквівалентний цикл "для 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's dict
не впорядковані, тому безглуздо просити "перші N" клавіші.
collections.OrderedDict
Клас доступний , якщо це те, що вам потрібно. Ви можете ефективно отримати свої перші чотири елементи як
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) у ітератор, а потім повторіть його з наступним ().
Не бачив тут. Не буде впорядковано, але найпростіше синтаксично, якщо вам потрібно просто взяти деякі елементи зі словника.
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]}
(акції - це назва мого словника)
Щоб отримати найпопулярніші N елементів зі свого словника python, можна скористатись наступним рядком коду:
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
.
До речі, чому ви дбаєте про «ефективний» спосіб? Ви профілювали свою програму? Якщо ви цього не зробили, спочатку скористайтеся очевидним і зрозумілим для вас способом. Швидше за все, це буде досить добре, не стаючи вузьким місцем.
Ви можете підійти до цього кількома способами. Якщо замовлення важливе, ви можете зробити це:
for key in sorted(d.keys()):
item = d.pop(key)
Якщо замовлення не хвилює, ви можете зробити це:
for i in range(4):
item = d.popitem()
value
а не item
для ясності.
Словник не підтримує порядку, тому перед тим, як вибрати верхнє 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, деякі твердження, які ви очікуєте працювати з упорядкованими структурами, здається, не працюють.
Відповідь на питання ОП, яке найкраще працювало для мене.
itr = iter(dic.items())
lst = [next(itr) for i in range(3)]
lst = list(d.items())[:N]
list(d.items())[:4]
. list () - основна реалізація багатьох відповідей.