Zak*_*Zak 38 python dictionary
我有一个字典,并希望将其中的一部分传递给一个函数,该部分由一个列表(或元组)给出.像这样:
# the dictionary
d = {1:2, 3:4, 5:6, 7:8}
# the subset of keys I'm interested in
l = (1,5)
Run Code Online (Sandbox Code Playgroud)
现在,理想情况下我希望能够做到这一点:
>>> d[l]
{1:2, 5:6}
Run Code Online (Sandbox Code Playgroud)
...但这不起作用,因为它会寻找一个名为的钥匙(1,5).并且d[1,5]甚至不是有效的Python(虽然看起来它会很方便).
我知道我可以这样做:
>>> dict([(key, value) for key,value in d.iteritems() if key in l])
{1: 2, 5: 6}
Run Code Online (Sandbox Code Playgroud)
或这个:
>>> dict([(key, d[key]) for key in l])
Run Code Online (Sandbox Code Playgroud)
这更紧凑...但我觉得必须有一个"更好"的方式来做到这一点.我错过了更优雅的解决方案吗?
(我使用的是Python 2.7)
Pad*_*ham 27
你应该迭代元组并检查密钥是否在dict中,而不是相反,如果你不检查密钥是否存在而且它不在dict中你将得到一个关键错误:
print({k:d[k] for k in l if k in d})
Run Code Online (Sandbox Code Playgroud)
一些时间:
{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
Run Code Online (Sandbox Code Playgroud)
我不知道如何{k:d[k] for k in l}不可读或优雅,如果所有元素都在d中,那么它非常有效.
Ces*_*ssa 23
在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}
Run Code Online (Sandbox Code Playgroud)
注意:此解决方案并没有考虑到特定按键.它按内部排序切片d,在Python 3.7+中保证按插入顺序排列.
Mar*_*ers 18
使用集合在dict.viewkeys()字典视图上相交:
l = {1, 5}
{key: d[key] for key in d.viewkeys() & l}
Run Code Online (Sandbox Code Playgroud)
这是Python 2的语法,在Python 3中使用d.keys().
这仍然使用循环,但至少字典理解更具可读性.使用集合交叉点非常有效,即使d或者l很大.
演示:
>>> d = {1:2, 3:4, 5:6, 7:8}
>>> l = {1, 5}
>>> {key: d[key] for key in d.viewkeys() & l}
{1: 2, 5: 6}
Run Code Online (Sandbox Code Playgroud)
小智 12
要对字典进行切片,请使用 将其转换为元组列表d.items(),对列表进行切片并从中创建字典。
这里。
d = {1:2, 3:4, 5:6, 7:8}
获取前 2 个项目
first_two = dict(list(d.items())[:2])
第一个_两个
{1: 2, 3: 4}
编写一个dict接受键列表作为"item" 的子类,并返回字典的"切片":
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)
Run Code Online (Sandbox Code Playgroud)
用法:
d = SliceableDict({1:2, 3:4, 5:6, 7:8})
d[[1, 5]] # {1: 2, 5: 6}
Run Code Online (Sandbox Code Playgroud)
或者,如果要对此类访问使用单独的方法,则可以使用*接受任意数量的参数:
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
Run Code Online (Sandbox Code Playgroud)
set intersection并dict comprehension可以在这里使用
# 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}
Run Code Online (Sandbox Code Playgroud)