使用深层嵌套的python dicts,我希望能够在这样的数据结构中分配值,如下所示:
mydict[key][subkey][subkey2]="value"
Run Code Online (Sandbox Code Playgroud)
无需检查mydict [key]等实际上是否设置为dict,例如使用
if not key in mydict: mydict[key]={}
Run Code Online (Sandbox Code Playgroud)
子代的创建应该在飞行中发生.什么是允许等价的最优雅方式 - 可能在标准上使用装饰器<type 'dict'>?
这个问题是关于在Python中实现完整的Perl自动修改.我知道之前提出过类似的问题,到目前为止,最好的答案是" 在Python中实现嵌套字典的最佳方法是什么? ".但是,我希望这样做:
a['x']['y'].append('z')
Run Code Online (Sandbox Code Playgroud)
没有a['x']['y'] = []首先声明,或者更确切地说,没有声明a['x'] = {}.(在Perl中你可以注意到push @{$a->{x}{y}}, 'z';.)
我知道dict和list类sorta不混合,所以这很难,但我有兴趣看看是否有人有一个巧妙的解决方案,可能涉及从中创建一个继承的类,dict但append在其上定义了一个新的方法?
我也知道这可能会让一些Python纯粹主义者想要我坚持使用Perl.但是,即使只是为了挑战,我也希望看到一些东西.
我尝试使用抽象基类MutableMapping在Python中实现映射,但是我在实例化时遇到了错误.我将如何dict使用抽象基类创建这个字典的工作版本,以尽可能多的方式模拟内置类?
>>> class D(collections.MutableMapping):
... pass
...
>>> d = D()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class D with abstract methods __delitem__, __getitem__, __iter__, __len__, __setitem__
Run Code Online (Sandbox Code Playgroud)
一个好的答案将演示如何使这项工作,特别是没有子类化dict(我非常熟悉的概念).
根据这个答案,我想创建一个单行树作为另一个类的一部分,如下所示:
self._tree = collections.defaultdict(lambda: self._tree)
Run Code Online (Sandbox Code Playgroud)
我需要允许所述类的用户将路径元素添加到树中,并从最低的树级开始运行一些回调.我运行时,我的天真实现会引发错误pytest:
def _add(self, tree, path):
for node in path:
tree = tree[node]
def _run(self, tree, callback):
for key in tree.keys():
callback(tree[key]) # !!! Recursion detected (same locals & position)
self._run(key)
Run Code Online (Sandbox Code Playgroud)
如果树定义为,则此代码有效
def tree():
return collections.defaultdict(tree)
self._tree = tree()
Run Code Online (Sandbox Code Playgroud)
为什么我的天真方法不适用于lambda表达式?
⚠Python的禅宗说明了这一点
简单比复杂更好.
单行lambda使代码复杂,实现更简单.因此,不应在生产代码中使用单行lambda .但是,我会在这里提出这个问题以获得学术兴趣.
TL; DR
在为子键分配值时,如何在Python dict中使超级密钥自动生成,而不检查子键时是否自动生成它们?
背景: 通常在Python中,在嵌套字典中设置值需要在分配给子键之前手动确保存在更高级别的键.那是,
my_dict[1][2] = 3
Run Code Online (Sandbox Code Playgroud)
如果没有先做类似的事情,将不会按预期可靠地工作
if 1 not in my_dict:
my_dict[1] = {}
Run Code Online (Sandbox Code Playgroud)
现在,可以通过创建my_dict覆盖类的实例来设置一种自动生成,__missing__例如在/sf/answers/1388080011/中所示.
问题:但是,如果您在这样的嵌套字典中检查是否存在子键,那么该解决方案会自动对高级别密钥进行自动生成.这导致以下不幸:
>>> vd = Vividict()
>>> 1 in vd
False
>>> 2 in vd[1]
False
>>> 1 in vd
True
Run Code Online (Sandbox Code Playgroud)
我怎样才能避免这种误导性的结果呢?顺便说一句,在Perl中,我可以通过这样做获得所需的行为
no autovivification qw/exists/;
Run Code Online (Sandbox Code Playgroud)
基本上我想在可能的情况下在Python中复制该行为.
我试图将对象列表转换为嵌套的dict,可以通过索引访问.
以下代码适用于两级嵌套字典.我想将它扩展到灵活地工作任意数量的级别.
from collections import namedtuple
import pprint
Holding = namedtuple('holding', ['portfolio', 'ticker', 'shares'])
lst = [
Holding('Large Cap', 'TSLA', 100),
Holding('Large Cap', 'MSFT', 200),
Holding('Small Cap', 'UTSI', 500)
]
def indexer(lst, indexes):
"""Creates a dynamic nested dictionary based on indexes."""
result = {}
for item in lst:
index0 = getattr(item, indexes[0])
index1 = getattr(item, indexes[1])
result.setdefault(index0, {}).setdefault(index1, [])
result[index0][index1].append(item)
return result
d = indexer(lst, ['portfolio', 'ticker'])
pp = pprint.PrettyPrinter()
pp.pprint(d)
Run Code Online (Sandbox Code Playgroud)
输出:
{'Large Cap': {'MSFT': [holding(portfolio='Large Cap', ticker='MSFT', shares=200)],
'TSLA': …Run Code Online (Sandbox Code Playgroud) 阅读后实现嵌套字典的最佳方法是什么?为什么这样做有误:
c = collections.defaultdict(collections.defaultdict(int))
Run Code Online (Sandbox Code Playgroud)
在python?我认为这可以产生
{key:{key:1}}
Run Code Online (Sandbox Code Playgroud)
或者我在想错了?
我有一个文本文件abc.txt:
abc/pqr/lmn/xyz:pass
abc/pqr/lmn/bcd:pass
Run Code Online (Sandbox Code Playgroud)
我需要解析这些语句,输出应该在嵌套字典中,如下所示:
{'abc':{'pqr':{'lmn':{'xyz':{'pass':1},{'bcd':{'pass':1}}}}}}
Run Code Online (Sandbox Code Playgroud)
其中 1 是'pass'计数。
我可以做这样的事情:
import re
d={}
p=re.compile('[a-zA-z]+')
for line in open('abc.txt'):
for key in p.findall(line):
d['key']={}
Run Code Online (Sandbox Code Playgroud) 这个主题并不新鲜,已经在多个帖子中讨论过(链接位于底部)。然而,我觉得资源分散,并不总是清楚什么是最好的方法。我还想引入一些约束来明确定义我期望的行为。
假设我们有一个包含任意数量的项目和任意深度的嵌套字典:
d = {"a": {"b": {"c" : 0}},
"b": {"c" : 1},
"c": 2}
Run Code Online (Sandbox Code Playgroud)
获取其物品的最佳方式是什么?
这种简单的方法相当麻烦,尤其是当有很多嵌套级别时。
>>> d["a"]["b"]["c"]
0
Run Code Online (Sandbox Code Playgroud)
因此,第一个约束是要获取的项的键必须以元组的形式提供,例如:
key = ("a", "b", "c")
Run Code Online (Sandbox Code Playgroud)
现在的目标是创建一些工作原理如下的函数:
>>> getitem(d, key)
0
Run Code Online (Sandbox Code Playgroud)
这种格式也可以方便地直接应用为__getitem__类的方法。
还有一个限制:我希望该函数在被要求获取不存在的密钥时大声失败。
>>> getitem(d, ("asd",))
...
KeyError: 'asd'
Run Code Online (Sandbox Code Playgroud)
这排除了所有使用项目获取来使字典生动的解决方案。
最后,如果可能,请提供低级代码。如果您知道解决此问题的包,请解释底层机制。
参考
我正在按照建议编写一个文本冒险游戏作为我的第一个 python 程序。我想列出狗可能吃的东西,它们有什么不好,以及它们有多糟糕。所以,我想我会这样做:
badfoods = []
keys = ['Food','Problem','Imminent death']
food1 = ['alcohol', 'alcohol poisoning', 0]
food2 = ['anti-freeze', 'ethylene glycol', 1]
food3 = ['apple seeds', 'cyanogenic glycosides', 0]
badfoods.append(dict(zip(keys,food1)))
badfoods.append(dict(zip(keys,food2)))
badfoods.append(dict(zip(keys,food3)))
Run Code Online (Sandbox Code Playgroud)
实际上我想包括大约 40 种食物。我知道我也可以这样做:
[{'Food':'alcohol', 'Problem':'alcohol poisoning', 'Imminent death':0},
{'Food':'anti-freeze', 'Problem':'ethylene glycol', 'Imminent death':1}
{'Food':'apple seeds, 'Problem':'cyanogenic glycosides', 'Imminent death':0}] ]
Run Code Online (Sandbox Code Playgroud)
我还在这里阅读了有关使用 YAML 的这篇文章,这很吸引人:实现嵌套字典的最佳方法是 什么? 但我仍然不知道如何避免大量写入密钥。
另外,我很恼火,我无法弄清楚避免编写 append 40 次的原始方法,即:
def poplist(listname, keynames, name):
listname.append(dict(zip(keynames,name)))
def main():
badfoods = []
keys = ['Food','Chemical','Imminent death']
food1 = ['alcohol', …Run Code Online (Sandbox Code Playgroud)