Perl有一个构造(称为"哈希切片"正如Joe Z指出的那样),用于索引到带有列表的哈希以获取列表,例如:
%bleah = (1 => 'a', 2 => 'b', 3 => 'c');
print join(' ', @bleah{1, 3}), "\n";
执行给出:
a c
我知道在Python中处理这个问题的最简单,最易读的方法是列表理解:
>>> bleah = {1: 'a', 2: 'b', 3: 'c'}
>>> print ' '.join([bleah[n] for n in [1, 3]])
a c
,因为:
>>> bleah[[1, 2]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
我还有其他一些更好的方法吗?也许在Python3中,我还没有做过多少呢?如果没有,是否有人知道是否已经为此提交了PEP?我的google-fu无法找到。
&#34;它不是Pythonic&#34;:是的,我知道,但我喜欢它。它是简洁易读,因为它永远不会是Pythonic索引到一个具有不可用类型的dict,让异常处理程序迭代索引而不是barfing不会打破大多数目前的代码。
注意:正如评论中指出的那样,这个测试用例可以重写为一个列表,完全避免使用dict,但我正在寻找一般解决方案。
答案 0 :(得分:4)
我能想到的最好方法是使用itemgetter
from operator import itemgetter
bleah = {1: 'a', 2: 'b', 3: 'c'}
getitems = itemgetter(1, 3)
print getitems(bleah)
所以,如果你想传递一个索引列表,那么你可以解压缩参数,就像这样(感谢@koffein指出这一点:))
getitems = itemgetter(*[1, 3])
然后你可以join
喜欢这个
print ' '.join(getitems(bleah))
或只是
print ' '.join(itemgetter(1, 3)(bleah))
答案 1 :(得分:1)
如果您的dict有连续的整数索引,那么您可以将其重建为列表并使用
bleah[1:3]
答案 2 :(得分:1)
目前,我正在评论中提出Hyperboreus的建议并覆盖__getitem__
,但我仍然认为让它成为默认的dict行为是有意义的:
jcomeau@aspire:~$ cat /tmp/sliceable.py; echo ---; python /tmp/sliceable.py
'SliceableDict test'
import sys, os
class SliceableDict(dict):
def __init__(self, d = {}):
super(SliceableDict, self).__init__(d)
def __getitem__(self, index):
try:
return super(SliceableDict, self).__getitem__(index)
except TypeError:
return [super(SliceableDict, self).__getitem__(x) for x in index]
def __setitem__(self, index, value):
try:
super(SliceableDict, self).__setitem__(index, value)
except:
for i in range(len(index)):
super(SliceableDict, self).__setitem__(index[i], value[i])
d = SliceableDict({1: 'a', 2: 'b', 3: 'c'})
print d[2]
print d[[1, 3]]
d[[1, 3]] = ['x', 'y']
print d
---
b
['a', 'c']
{1: 'x', 2: 'b', 3: 'y'}
(修改为根据上面的tobyink评论添加左值功能 - jc 2013-12-12)
答案 3 :(得分:0)
我会说这是略微更好,因为如果由于某种原因传递了一个未知密钥,你有一个默认值,它避免了不必要的内部列表和导入(如@thefourtheye的例子): / p>
bleah = {1: 'a', 2: 'b', 3: 'c'}
print(' '.join(bleah.get(i, '') for i in (1, 3)))
如果您只想要一个返回值列表:
list(bleah.get(i) for i in (1, 3))
此处无需默认值,因为get
的默认值为None
。 None
无法转换为字符串,这就是我在打印示例中传入空字符串的原因。