Soru Python - İlk N tuşuna dönüş: dict'dan değer çiftleri


Aşağıdaki sözlüğü düşünün, d:

d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}

İlk N anahtarını döndürmek istiyorum: değer çiftleri d (bu durumda N <= 4). Bunu yapmanın en etkili yöntemi nedir?


44
2017-11-01 19:15


Menşei




Cevaplar:


"İlk n" tuşları diye bir şey yok çünkü dict önce hangi anahtarların eklendiğini hatırlamıyor.

Alabilirsiniz herhangi n anahtar-değer çiftleri olsa:

n_items = take(n, d.iteritems())

Bu uygulamayı kullanır take itibaren itertools yemek tarifleri:

from itertools import islice

def take(n, iterable):
    "Return first n items of the iterable as a list"
    return list(islice(iterable, n))

Çevrimiçi çalışırken bakın: ideone


59
2017-11-01 19:18



inanıyorum iteritems ile değiştirilmelidir items Python 3 millet için - Monica Heddneck


Bir şeyi geri kazanmanın çok etkili bir yolu, liste ya da sözlük anlamalarını dilimleme ile birleştirmektir. Öğeleri sipariş etmeniz gerekmiyorsa (sadece rastgele çiftler istiyorsanız), aşağıdaki gibi bir sözlük kavrayışını kullanabilirsiniz:

# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}

Genel olarak böyle bir kavrama, her zaman için "x in y" döngüsünden daha hızlı koşmaktan daha hızlıdır. Ayrıca, sözlük anahtarlarının bir listesini yapmak ve bu listeyi dilimlemek için .keys () öğesini kullanarak, yeni sözlüğü oluştururken gereksiz tuşlara 'dokunmaktan' kaçınabilirsiniz.

Anahtarlara ihtiyacınız yoksa (sadece değerler) liste kavramasını kullanabilirsiniz:

first2vals = [v for v in mydict.values()[:2]]

Anahtarlarına göre sıralanmış değerlere ihtiyacınız varsa, daha fazla sorun olmaz:

first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]

ya da tuşlara da ihtiyacınız varsa:

first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}

30
2017-10-19 18:43



Bir çok anahtar: değer çiftini bir sözlük olarak seçmek istiyorsanız, liste olarak değil de, bu daha iyi bir çözümdür. - fermat4214
@ fermat4214 Bu komutlardan herhangi birini çalıştırdığımda tüm sözlüğüm yazdırıyorsa sorun mu var? - Ted Taylor of Life


Python en dicts sipariş edilmez, bu yüzden "ilk N" tuşlarını sormak anlamsızdır.

collections.OrderedDict ihtiyacınız olan buysa, sınıf kullanılabilir. İlk dört elementini verimli bir şekilde alabilirsiniz.

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 herhangi bir yineleyiciden bir dilim öğeyi rahatça çekmenizi sağlar. Eğer sonucun tekrar kullanılabilir olmasını istiyorsanız, onu bir listeye veya başka bir şeye dönüştürmeniz gerekir:

x = list(itertools.islice(d.items(), 0, 4))

9
2017-11-01 19:18





Görmek PEP 0265 sözlükleri sıralama. Ardından, yukarıda bahsedilen yinelenen kodu kullanın.

Sıralanan anahtar / değer çiftlerinde daha fazla verimliliğe ihtiyacınız varsa. Farklı bir veri yapısı kullanın. Yani sıralı düzeni ve anahtar-değer ilişkilerini koruyan bir tanesi.

Örneğin.

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)]

3
2017-11-01 19:30





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))

Temel olarak, görünümü (dict_items) bir yineleyiciye dönüştürün ve ardından bir sonraki ile yineleyin ().


3
2017-09-20 12:05



Fantastik cevap, bu sayfa benim için çalıştı ve aynı zamanda okunabilir tek cevaptır. Ayrıca, bu çalışmaların bazı eski cevapların görünmediği Python 3 ile de doğrulayabilirim. - cdahms


Burada görmedim. Bir sözlükten bazı öğeler almanız gerekiyorsa, sipariş edilmeyecek, ancak en basit sözdizimsel olacaktır.

n = 2
{key:value for key,value in d.items()[0:n]}

2
2018-01-27 02:53



Kodu denedim ama şu hatayı alıyorum: TypeError: 'dict_items' object is not subscriptable  {key:value for key,value in stocks.items()[0:n]}     (hisse senetleri sözlükimin adıdır) - Moondra
@Moondra - Sözlük öğeleri ile çalıştırmadan önce listeye dönüştürmek zorunda. Kodun üstünde satır {key: anahtar için değer, listedeki değer (d.items ()) [0: n]} ise çalışır - Rajesh Mappu


Bu sizin durumunuzda 'en verimli' olana bağlıdır.

Büyük bir sözlüğün yarı rastgele bir örneğini istiyorsanız foo, kullan foo.iteritems() ve ihtiyacınız olduğu kadar çok değer almak, açık bir anahtar veya öğe listesi oluşturulmasını engelleyen tembel bir işlemdir.

Önce anahtarları sıralamanız gerekiyorsa, keys = foo.keys(); keys.sort() veya sorted(foo.iterkeys())Açık bir anahtar listesi oluşturmalısınız. Sonra ilk N ile dilimleyin veya tekrarlayın keys.

BTW Neden 'etkili' yolu umursuyorsunuz? Programına baktın mı? Eğer yapmadıysanız, açık ve anlaması kolay önce yol. Şanslar bir darboğaz olmaksızın oldukça iyi olacak.


1
2017-11-01 19:37



Bu bir finansal program için bir başvuruydı ve her satırdaki kodu mümkün olduğunca verimli bir şekilde oluşturmaya çalışıyorum. Programı izlemedim ve bunun muhtemelen bir şişe boynu olmadığına katılıyorum, ancak varsayılan olarak verimli çözümler istemek istiyorum. Cevap için teşekkürler. - Jason Strimpel


Buna birkaç yönden yaklaşabilirsiniz. Sipariş önemliyse bunu yapabilirsiniz:

for key in sorted(d.keys()):
  item = d.pop(key)

Sipariş bir sorun değilse, bunu yapabilirsiniz:

for i in range(4):
  item = d.popitem()

0
2017-11-01 19:18



İlk snippet’te muhtemelen onu çağırmalısınız value ziyade item açıklık için. - agf


Sözlük hiçbir sırayı korur, bu yüzden en üstteki N tuş değer çiftlerini seçmeden önce sıralamasını sağlar.

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

Şimdi üstteki 'N' elemanlarının geri alınmasını yapabiliriz:

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

En iyi 2 elemanı elde etmek için bu yapıyı kullanın:

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)

0
2017-09-12 11:52