Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 切分字典_Python_Dictionary - Fatal编程技术网

Python 切分字典

Python 切分字典,python,dictionary,Python,Dictionary,我有一个字典,希望将它的一部分传递给函数,该部分由键列表(或元组)给出。像这样: # the dictionary d = {1:2, 3:4, 5:6, 7:8} # the subset of keys I'm interested in l = (1,5) 现在,理想情况下,我希望能够做到这一点: >>> d[l] {1:2, 5:6} 。。。但这不起作用,因为它将查找名为(1,5)的密钥。 而且d[1,5]甚至不是有效的Python(尽管它似乎很方便) 我知道我能

我有一个字典,希望将它的一部分传递给函数,该部分由键列表(或元组)给出。像这样:

# the dictionary
d = {1:2, 3:4, 5:6, 7:8}

# the subset of keys I'm interested in
l = (1,5)
现在,理想情况下,我希望能够做到这一点:

>>> d[l]
{1:2, 5:6}
。。。但这不起作用,因为它将查找名为
(1,5)
的密钥。 而且
d[1,5]
甚至不是有效的Python(尽管它似乎很方便)

我知道我能做到:

>>> dict([(key, value) for key,value in d.iteritems() if key in l])
{1: 2, 5: 6}
或者这个:

>>> dict([(key, d[key]) for key in l])
哪个更紧凑 ... 但我觉得必须有一个“更好”的方法来做到这一点。我是否错过了一个更优雅的解决方案


(我使用的是Python 2.7)

使用一个集合在以下对象上相交:

这是Python2语法,在Python3中使用
d.keys()

这仍然使用循环,但至少字典理解更具可读性。使用集合交点非常有效,即使
d
l
很大

演示:


使用一个集合在以下对象上相交:

这是Python2语法,在Python3中使用
d.keys()

这仍然使用循环,但至少字典理解更具可读性。使用集合交点非常有效,即使
d
l
很大

演示:


您应该迭代元组并检查键是否在dict中,而不是相反,如果不检查键是否存在并且不在dict中,您将得到一个键错误:

print({k:d[k] for k in l if k in d})
一些时间安排:

 {k:d[k] for k in set(d).intersection(l)}

In [22]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in l}
   ....: 
100 loops, best of 3: 11.5 ms per loop

In [23]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in set(d).intersection(l)}
   ....: 
10 loops, best of 3: 20.4 ms per loop

In [24]: %%timeit                        
l = xrange(100000)
l = set(l)                              
{key: d[key] for key in d.viewkeys() & l}
   ....: 
10 loops, best of 3: 24.7 ms per

In [25]: %%timeit                        

l = xrange(100000)
{k:d[k] for k in l if k in d}
   ....: 
100 loops, best of 3: 17.9 ms per loop

我看不出
{k:d[k]for k in l}
是如何不可读或不优雅的,如果所有元素都在d中,那么它是非常有效的。

您应该迭代元组并检查键是否在dict中,而不是相反,如果您不检查键是否存在并且它不在dict中,您将得到一个键错误:

print({k:d[k] for k in l if k in d})
一些时间安排:

 {k:d[k] for k in set(d).intersection(l)}

In [22]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in l}
   ....: 
100 loops, best of 3: 11.5 ms per loop

In [23]: %%timeit                        
l = xrange(100000)
{k:d[k] for k in set(d).intersection(l)}
   ....: 
10 loops, best of 3: 20.4 ms per loop

In [24]: %%timeit                        
l = xrange(100000)
l = set(l)                              
{key: d[key] for key in d.viewkeys() & l}
   ....: 
10 loops, best of 3: 24.7 ms per

In [25]: %%timeit                        

l = xrange(100000)
{k:d[k] for k in l if k in d}
   ....: 
100 loops, best of 3: 17.9 ms per loop

我不明白
{k:d[k]for k in l}
是如何不可读或不优雅的,如果所有元素都在d中,那么它是非常有效的。

编写一个
dict
子类,该子类接受键列表作为“项”,并返回字典的“切片”:

class SliceableDict(dict):
    default = None
    def __getitem__(self, key):
        if isinstance(key, list):   # use one return statement below
            # uses default value if a key does not exist
            return {k: self.get(k, self.default) for k in key}
            # raises KeyError if a key does not exist
            return {k: self[k] for k in key}
            # omits key if it does not exist
            return {k: self[k] for k in key if k in self}
        return dict.get(self, key)
用法:

d = SliceableDict({1:2, 3:4, 5:6, 7:8})
d[[1, 5]]   # {1: 2, 5: 6}
或者,如果要对这种类型的访问使用单独的方法,可以使用
*
接受任意数量的参数:

class SliceableDict(dict):
    def slice(self, *keys):
        return {k: self[k] for k in keys}
        # or one of the others from the first example

d = SliceableDict({1:2, 3:4, 5:6, 7:8})
d.slice(1, 5)     # {1: 2, 5: 6}
keys = 1, 5
d.slice(*keys)    # same

编写一个
dict
子类,该子类接受键列表作为“项”,并返回字典的“切片”:

class SliceableDict(dict):
    default = None
    def __getitem__(self, key):
        if isinstance(key, list):   # use one return statement below
            # uses default value if a key does not exist
            return {k: self.get(k, self.default) for k in key}
            # raises KeyError if a key does not exist
            return {k: self[k] for k in key}
            # omits key if it does not exist
            return {k: self[k] for k in key if k in self}
        return dict.get(self, key)
用法:

d = SliceableDict({1:2, 3:4, 5:6, 7:8})
d[[1, 5]]   # {1: 2, 5: 6}
或者,如果要对这种类型的访问使用单独的方法,可以使用
*
接受任意数量的参数:

class SliceableDict(dict):
    def slice(self, *keys):
        return {k: self[k] for k in keys}
        # or one of the others from the first example

d = SliceableDict({1:2, 3:4, 5:6, 7:8})
d.slice(1, 5)     # {1: 2, 5: 6}
keys = 1, 5
d.slice(*keys)    # same

这里可以使用
设置交叉点
听写理解

# the dictionary
d = {1:2, 3:4, 5:6, 7:8}

# the subset of keys I'm interested in
l = (1,5)

>>>{key:d[key] for key in set(l) & set(d)}
{1: 2, 5: 6}

这里可以使用
设置交叉点
听写理解

# the dictionary
d = {1:2, 3:4, 5:6, 7:8}

# the subset of keys I'm interested in
l = (1,5)

>>>{key:d[key] for key in set(l) & set(d)}
{1: 2, 5: 6}

在Python3上,可以使用itertools
islice
dict.items()迭代器进行切片

import itertools

d = {1: 2, 3: 4, 5: 6}

dict(itertools.islice(d.items(), 2))

{1: 2, 3: 4}

注意:此解决方案不考虑特定键。它通过
d
的内部顺序进行切片,在Python 3.7+中保证插入顺序。

在Python 3上,您可以使用itertools
islice
来切片
dict.items()
迭代器

import itertools

d = {1: 2, 3: 4, 5: 6}

dict(itertools.islice(d.items(), 2))

{1: 2, 3: 4}
注意:此解决方案不考虑特定键。它按照
d
的内部顺序进行切片,在Python 3.7+中,保证按插入顺序进行切片。

字典 我感兴趣的密钥子集 回答
{key:d[key]表示l中的key}
字典 我感兴趣的密钥子集 回答
{key:d[key]表示l中的key}

要对词典进行切片,请使用
d.items()
将其转换为元组列表,切片列表并从中创建词典

在这里

d={1:2,3:4,5:6,7:8}

要获取前2项

first\u two=dict(list(d.items())[:2])

头两个


{1:2,3:4}

要将字典切片,请使用
d.items()
将其转换为元组列表,切片列表并从中创建字典

在这里

d={1:2,3:4,5:6,7:8}

要获取前2项

first\u two=dict(list(d.items())[:2])

头两个


{1:2,3:4}

这有什么问题吗
{key:d[key]for key in l}
@itzmeontv:如果您知道
l
中的所有键都在
d
中,那么这不是问题。但是使用
d.viewkeys()&l
会产生交集,在
d
和集合
l
中都存在的键。哦,明白了:)
{key:d[key]对于key-in-l如果key-in-d}
会变得奇怪吗?@itzmeontv:那么如果
l
是大的而
d
是小的呢?把这个问题留给Python来创建交集,而不必自己循环。这有问题吗
{key:d[key]for key in l}
@itzmeontv:如果您知道
l
中的所有键都在
d
中,那么这不是问题。但是使用
d.viewkeys()&l
会产生交集,在
d
和集合
l
中都存在的键。哦,明白了:)
{key:d[key]对于key-in-l如果key-in-d}
会变得奇怪吗?@itzmeontv:那么如果
l
是大的而
d
是小的呢?让Python自己创建交集,而不必自己循环。这个主意很酷,不过我宁愿添加一个额外的属性,也不想弄乱现有的函数。类似于
d.slice(l)
。事实上,我一直希望这样的事情存在。比循环更具可读性。当然,编写另一个方法非常方便,或者您可以使用
\uuuu调用\uuuu
。我不会说第一个建议是cromulent。使用
d
的任何其他代码都会期望
[
具有通常的语义,但它们会发生变化。
切片
示例是cromulent。@KenWilliams的观点很好。也许更好的方法是为此传递一个列表。通常不能将列表用作字典键,因此您需要