Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.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
使用list索引到Python dict中以获取列表,就像使用Perl散列一样_Python_Perl_Dictionary_Hash - Fatal编程技术网

使用list索引到Python dict中以获取列表,就像使用Perl散列一样

使用list索引到Python dict中以获取列表,就像使用Perl散列一样,python,perl,dictionary,hash,Python,Perl,Dictionary,Hash,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'} >>

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'
>bleah[[1,2]]
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
还有其他更好的方法让我错过吗?也许在Python3中,我还没有用它做很多事情?如果没有,是否有人知道是否已经为此提交了政治公众人物?我的google fu找不到一个

“它不是Pythonic”:是的,我知道,但我希望它是。它简洁易读,而且由于索引到具有不可破坏类型的dict中永远不会是python式的,因此让异常处理程序为您迭代索引而不是barfing不会破坏大多数当前代码


注意:正如在评论中指出的,这个测试用例可以重写为一个列表,完全避免使用dict,但我正在寻找一个通用的解决方案。

如果dict有连续的整数索引,那么您可以将它重建为一个列表并使用它

bleah[1:3]

我能想到的最好的方法是使用
itemgetter

from operator import itemgetter
bleah = {1: 'a', 2: 'b', 3: 'c'}
getitems = itemgetter(1, 3)
print getitems(bleah)
因此,如果您想要传递一个索引列表,那么您可以像这样解压参数(感谢@koffein指出这一点:)

然后你可以像这样加入

print ' '.join(getitems(bleah))
或者干脆

print ' '.join(itemgetter(1, 3)(bleah))
我想说这稍微好一点,因为如果出于某种原因传递了一个未知键,那么您有一个默认值,并且它避免了不必要的内部列表和导入(如@thefourtheye的示例):

如果您只需要返回值的列表:

list(bleah.get(i) for i in (1, 3))

此处不需要默认值,因为
get
的默认值为
None
<代码>无无法转换为字符串,这就是我在打印示例中传入空字符串的原因。

现在,我在注释中采纳了Hyperboreus的建议,并覆盖了
\uu getitem\uuuuuu
,但我仍然认为将其作为默认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'}

(根据上面Tobynk的评论修改为添加左值功能--jc 2013-12-12)

顺便说一句,上面使用的Perl特性的名称是“哈希切片”。使用列表代替字典怎么样?在本例中,我可以,但这只是一个说明性的测试用例。我认为这样做会很好,但结果应该是什么呢?价值或项目的列表?副词?我认为使用
bleah.items([1,3])
返回
[('1','a'),('3','c')]
bleah.values([1,3])
返回
['a','c']
我不知道是否有任何答案考虑过这一点,但在Perl中,哈希片是一个左值。例如,你可以在如下的散列中为键“a”和“c”赋值:
@hash{a”,“c”}=split“|”,“foo | bar”
不,因为它是一个dict,而不是一个列表。一个具有整数索引的dict应该很容易重构成一个列表。夸张地说,是的,但我只是给出了一个简单的例子。@jcomeau|ictx在perl
@bleah{1,4}
中的意思是“键1、2、3、4”或“键1和4”?它的意思是:键1和4+1很好。但是OP想要传递一个列表,所以你可以使用
itemgetter(*[1,3])
(或添加它)@koffein谢谢:)更新了我的答案。更直接地说,你可以只做
print'。加入(itemgetter(1,3)[bleah])
@thefortheye first,
[bleah]
在我的评论中是一个输入错误,意思是
(bleah)
。其次,不需要列表,但是如果列表中已经有了它们(例如,变量而不是文本键),您可以使用
*
将其解压到
itemgetter
的各个参数中。我尝试了,itemgetter()返回了一个元组。当然,编写列表很容易(itemgetter(1,3)(bleah))但这给我所寻找的干净的解决方案又添了一点污点。一方面,我认为这是一个有用的好主意(+1),另一方面
d[(1,3)]
d[[1,3]]
将返回/表示不同的内容。我不确定这是否值得引起混淆…这可能对某些人有用。我通常希望在使用不存在的密钥时引发异常。
list(bleah.get(i) for i in (1, 3))
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'}