2011-11-01 110 views

回答

54

“前n个”键不存在,因为dict不记得先插入了哪些键。

你可以得到任何 n键 - 值对,但:

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

它使用的take实施从itertools recipes

from itertools import islice 

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

看到它联机工作:ideone

+6

我相信'iteritems'应该用'items'关于Python 3 –

8

Python的dict s没有排序,所以请求“第一个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)) 
0

可以接近这个多种方式。如果订单不是问题,你可以做到这一点

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

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

取代了人们在第一个片段你应该把它叫做'价值而不是“项目”。 – agf

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

这取决于你的情况是什么'最有效'。

如果您只是想要一个大型字典foo的半随机样本,请使用foo.iteritems(),并根据需要从中获取尽可能多的值,这是一种懒惰操作,可避免创建明确的键或项目列表。

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

顺便说一句为什么你关心'高效'的方式?你有没有介绍你的计划?如果没有,首先使用明显的易于理解的方式。它很可能会做得很好,而不会成为瓶颈。

+0

这是一个财务程序的应用程序,我试图尽可能高效地构建每一行代码。我没有介绍该计划,并认为这可能不是瓶颈,但我希望默认情况下要求有效的解决方案。谢谢回复。 –

23

检索任何东西的一种非常有效的方法是将列表或词典解析与切片相结合。如果没有需要订购的物品(你只想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]} 
+0

这是一个更好的解决方案,如果你想选择许多键:值对作为字典,而不是列表 – fermat4214

+0

@ fermat4214这是一个问题,如果我的整个字典打印出来,当我运行这些命令中的任何一个? –

3

没有看到它在这里。如果您需要从字典中取出某些元素,将不会被排序,而是最简单的语法。

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

我试过了你的代码,但是我得到这个错误: 'TypeError:'dict_items'的对象不是可以下标的' '{key:value,value in stocks.items()[0:n]}'我的字典的名字) – Moondra

0

词典没有维护顺序,因此在选择前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) 
0
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()迭代它。

0

对于Python 3及以上的,要选择第一N对

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