我有一个数据结构,基本上相当于嵌套字典.让我们说它看起来像这样:
{'new jersey': {'mercer county': {'plumbers': 3,
'programmers': 81},
'middlesex county': {'programmers': 81,
'salesmen': 62}},
'new york': {'queens county': {'plumbers': 9,
'salesmen': 36}}}
Run Code Online (Sandbox Code Playgroud)
现在,保持和创造这个是非常痛苦的; 每当我有一个新的州/县/专业时,我必须通过令人讨厌的try/catch块创建下层词典.而且,如果我想要遍历所有值,我必须创建恼人的嵌套迭代器.
我也可以使用元组作为键,如下:
{('new jersey', 'mercer county', 'plumbers'): 3,
('new jersey', 'mercer county', 'programmers'): 81,
('new jersey', 'middlesex county', 'programmers'): 81,
('new jersey', 'middlesex county', 'salesmen'): 62,
('new york', 'queens county', 'plumbers'): 9,
('new york', 'queens county', 'salesmen'): 36}
Run Code Online (Sandbox Code Playgroud)
这使得迭代值非常简单和自然,但是做聚合和查看字典的子集(例如,如果我只想逐个状态)这样做更具语法上的痛苦.
基本上,有时我想将嵌套字典视为平面字典,有时我想将其视为复杂的层次结构.我可以把它全部包装在一个类中,但似乎有人可能已经完成了这个.或者,似乎可能有一些非常优雅的语法结构来做到这一点.
我怎么能做得更好?
附录:我知道setdefault()但它并没有真正实现干净的语法.此外,您创建的每个子词典仍需要setdefault()手动设置.
在Perl很多次,我会做这样的事情:
$myhash{foo}{bar}{baz} = 1
Run Code Online (Sandbox Code Playgroud)
我怎么把它翻译成Python?到目前为止,我有:
if not 'foo' in myhash:
myhash['foo'] = {}
if not 'bar' in myhash['foo']:
myhash['foo']['bar'] = {}
myhash['foo']['bar']['baz'] = 1
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
如果我理解正确,呼召if (exists $ref->{A}->{B}->{$key}) { ... }将会存在$ref->{A},$ref->{A}->{B}即使它们之前不存在if!
这似乎非常不受欢迎.那么我该如何检查是否存在"深度"哈希键?
有什么比这简单的方法
if hash.key?('a')
hash['a']['b'] = 'c'
else
hash['a'] = {}
hash['a']['b'] = 'c'
end
Run Code Online (Sandbox Code Playgroud) ruby hash variable-assignment autovivification hash-of-hashes
所以我正在编写一个扩展字典的类,该字典现在使用一种方法"dictify"将自身转换为字典.我想做的是改变它,以便在对象上调用dict()导致相同的行为,但我不知道要覆盖哪个方法.这是不可能的,还是我错过了一些完全明显的东西?(是的,我知道下面的代码不起作用,但我希望它能说明我正在尝试做什么.)
from collections import defaultdict
class RecursiveDict(defaultdict):
'''
A recursive default dict.
>>> a = RecursiveDict()
>>> a[1][2][3] = 4
>>> a.dictify()
{1: {2: {3: 4}}}
'''
def __init__(self):
super(RecursiveDict, self).__init__(RecursiveDict)
def dictify(self):
'''Get a standard dictionary of the items in the tree.'''
return dict([(k, (v.dictify() if isinstance(v, dict) else v))
for (k, v) in self.items()])
def __dict__(self):
'''Get a standard dictionary of the items in the tree.'''
print [(k, v) for (k, v) in self.items()]
return dict([(k, (dict(v) if …Run Code Online (Sandbox Code Playgroud) 搜索PHP.net进行自动更新无法获得任何结果.在撰写本文时,维基百科声称只有Perl拥有它.在Google搜索"php autovivification" 时,没有明确的确定结果.
这个PHP代码运行正常:
$test['a'][4][6]['b'] = "hello world";
var_dump($test);
array
'a' =>
array
4 =>
array
'b' =>
array
...
Run Code Online (Sandbox Code Playgroud)
任何人都可以提供PHP确实具有此功能的规范答案(最好使用引用),以及任何细节,例如它引入的版本,怪癖,快捷方式等?
在Python中,我可以创建一个散列,其中每个元素在首次引用时都具有默认值(也称为"autovivification").这是一个例子:
from collections import defaultdict
d = defaultdict(int)
d["new_key"] += 1
print d
Run Code Online (Sandbox Code Playgroud)
打印dict显示"new_key"的值为1.
Ruby中的等价物是什么?此代码抛出错误:
d = {}
d[:new_key] += 1
puts d
test.rb:3:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
Run Code Online (Sandbox Code Playgroud) ruby python dictionary language-comparisons autovivification
我很难理解为什么以下有效:
my $array_reference;
foreach $element (@{$array_reference}) {
# some code
}
Run Code Online (Sandbox Code Playgroud)
而以下不起作用
my $array_reference;
if (scalar (@{$array_reference}) {
# some code here
}
Run Code Online (Sandbox Code Playgroud)
我知道perl带来生命(自动生存)未定义的引用.但我仍然感到困惑,因为后一个代码段抛出FATAL.
谷歌和在线文档都没有提供我的查询的很多见解,所以我想我会在这里问社区.
在Perl中,您可以轻松设置哈希哈希哈希值并测试最终密钥,如下所示:
my $hash = {};
$hash{"element1"}{"sub1"}{"subsub1"} = "value1";
if (exists($hash{"element1"}{"sub1"}{"subsub1"})) {
print "found value\n";
}
Run Code Online (Sandbox Code Playgroud)
什么是Python中的"最佳实践"等价物?
在寻找使用嵌套字典的方法时,我发现nosklo发布了以下代码,我想解释一下.
class AutoVivification(dict):
"""Implementation of perl's autovivification feature."""
def __getitem__(self, item):
try:
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
return value
Run Code Online (Sandbox Code Playgroud)
测试:
a = AutoVivification()
a[1][2][3] = 4
a[1][3][3] = 5
a[1][2]['test'] = 6
print a
Run Code Online (Sandbox Code Playgroud)
输出:
{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}
Run Code Online (Sandbox Code Playgroud)
我是一个非常新手的程序员.我在自己的时间里学到了大部分我所知道的知识,我在高中时只接受过Turbo Pascal的正式训练.我理解并能够以简单的方式使用类,例如使用__init__类方法,并在类的实例中存储数据foo.man = 'choo'.
我不知道方括号系列如何正确地通过类(我假设它们__getitem__以某种方式调用)并且不明白它们如何被如此简洁地处理而不必单独调用该方法三次.
我的印象是(dict),班级声明中的处理方式是由__init__.
我以前用过的try: except:方式非常简单.它看起来像是在try运行时调用一系列函数__getitem__.我知道如果当前级别的字典存在,则try将通过并转到下一个字典.的except,我推测,运行有一个时候KeyError,但我还没有看到self …
autovivification ×10
python ×6
dictionary ×5
perl ×3
hash ×2
ruby ×2
mapping ×1
overriding ×1
php ×1