Python - 返回第一个N键:来自dict的值对

时间:2011-11-01 19:15:35

标签: python dictionary

考虑以下字典,d:

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

我想从d返回前N个键:值对(在这种情况下N <= 4)。这样做最有效的方法是什么?

20 个答案:

答案 0 :(得分:77)

没有“前n”键,因为dict不记得先插入了哪些键。

您可以获得任何 n个键值对:

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

这使用了itertools recipes

take的实现
from itertools import islice

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

查看在线工作:ideone

答案 1 :(得分:58)

检索任何内容的一种非常有效的方法是将列表或字典理解与切片相结合。如果您不需要订购商品(您只需要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]}

答案 2 :(得分:9)

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

答案 3 :(得分:5)

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()进行迭代。

答案 4 :(得分:3)

有关排序字典的信息,请参阅PEP 0265。然后使用前面提到的可迭代代码。

如果您需要在排序的键值对中提高效率。使用不同的数据结构。也就是说,维护排序顺序和键值关联。

E.g。

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

答案 5 :(得分:3)

这里没有看到它。如果您需要从字典中获取一些元素,则不会被排序,但最简单的语法。

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

答案 6 :(得分:1)

这取决于您案件中“最有效”的内容。

如果您只想要一个大型字典foo的半随机样本,请使用foo.iteritems()并根据需要从中获取尽可能多的值,这是一个惰性操作,可以避免创建显式列表钥匙或物品。

如果您需要先对键进行排序,则无法使用keys = foo.keys(); keys.sort()sorted(foo.iterkeys())之类的内容,您必须构建明确的键列表。然后切片或迭代第一个N keys

BTW为什么你关心'有效'的方式?你有没有介绍你的程序?如果没有,请先使用明显的易于理解的方式。如果不成为瓶颈,它很可能会很好。

答案 7 :(得分:1)

对于 Python 3.8 ,正确答案应为:

import more_itertools

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

first_n = more_itertools.take(3, d.items())
print(len(first_n))
print(first_n)

其输出是:

3
[('a', 3), ('b', 2), ('c', 3)]

当然在pip install more-itertools之后。

答案 8 :(得分:0)

您可以通过对字典调用 .items() 来获取字典项。然后将其转换为 list 并从那里获得前 N 个项目,就像在任何列表中一样。

下面的代码打印字典对象的前 3 项

例如

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

first_three_items = list(d.items())[:3]

print(first_three_items)

输出:

[('a', 3), ('b', 2), ('c', 3)]

答案 9 :(得分:0)

d是您的词典,n是印刷号码:

for idx, (k, v) in enumerate(d):
  if idx == n: break
  print((k, v))

将字典投射到列表可能很慢。您的词典可能太大了,您不必仅将其中的一部分先打印就可以全部投射。

答案 10 :(得分:0)

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

不寻常的方法,因为它散发出强烈的O(N)时间复杂度。

答案 11 :(得分:0)

在py3中,这可以解决问题

{A:N for (A,N) in [x for x in d.items()][:4]}

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

答案 12 :(得分:0)

我尝试了上面的一些答案,请注意,其中一些是依赖于版本的,在3.7版中不起作用。

我还注意到,自3.6开始,所有字典均按插入项目的顺序排序。

尽管从3.6开始就对字典进行了排序,但是您希望使用有序结构的某些语句似乎不起作用。

最适合我的OP问题答案。

itr = iter(dic.items())
lst = [next(itr) for i in range(3)]

答案 13 :(得分:0)

要从python字典中获取前N个元素,可以使用以下代码行:

list(dictionaryName.items())[:N]

您可以将其更改为:

list(d.items())[:4]

答案 14 :(得分:0)

这可能不是很优雅,但是对我有用:

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

答案 15 :(得分:0)

只需使用zip添加答案,

{k: d[k] for k, _ in zip(d, range(n))}

答案 16 :(得分:0)

考虑字典

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

from itertools import islice
n = 3
list(islice(d.items(),n))

islice将解决问题:) 希望对您有所帮助!

答案 17 :(得分:0)

对于Python 3及更高版本,要选择前n对

n=4
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]}

答案 18 :(得分:0)

字典维护没有顺序,所以在选择前N个键值对之前,让它排序。

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 57" 
    version="1.1" x="0px" y="0px">
    <defs>
      <linearGradient id="horizontalPipe" x2="0" y2="1">
        <stop offset="0" stop-color="white"/>
        <stop offset="0.25" stop-color="black"/>
        <stop offset="0.75" stop-color="black"/>
        <stop offset="1" stop-color="white"/>
      </linearGradient>
      <linearGradient id="verticalPipe">
        <stop offset="0" stop-color="white"/>
        <stop offset="0.25" stop-color="black"/>
        <stop offset="0.75" stop-color="black"/>
        <stop offset="1" stop-color="white"/>
      </linearGradient>
      <radialGradient id="curvedPipe" cx="0" cy="0" r="1">
        <stop offset="0.57" stop-color="white"/>
        <stop offset="0.677" stop-color="black"/>
        <stop offset="0.893" stop-color="black"/>
        <stop offset="1" stop-color="white"/>
      </radialGradient>
    </defs>
    
    <rect x="8" y="40" width="19" height="12" fill="url(#horizontalPipe)"/>
    <path d="M 27,40 A 16,16, 0,0,0 43,24 H 55 A 28,28, 0,0,1, 27,52 Z" fill="url(#curvedPipe)"/>
    <rect x="43" y="8" width="12" height="16" fill="url(#verticalPipe)"/>
</svg>

现在我们可以检索顶级&#39; N&#39; elements:,使用如下方法结构:

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

获取前2个元素然后只需使用此结构:

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

答案 19 :(得分:0)

你可以通过多种方式解决这个问题。如果订单很重要,您可以这样做:

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

如果订单不是问题,您可以这样做:

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