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上,您可以使用itertoolsislice
来切片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的观点很好。也许更好的方法是为此传递一个列表。通常不能将列表用作字典键,因此您需要