将值添加到默认字典值列表

Sco*_*oby 4 python python-2.7 python-3.x

蟒蛇问题:

我有一个默认的 dict/dict ,a[1] = (1,2,3)这样说a[1][0] = 1等等。现在我想添加到同一键上的值列表中。请理解,我不想追加,而是在同一列表中添加更多值。例如,我想将 5 添加到键 a[1] 但只在单个列表中,因此:

a[1][1].append("5") = (1, [2,5], 3) 
Run Code Online (Sandbox Code Playgroud)

有什么可以帮助我做到这一点吗?

aba*_*ert 5

你问:

\n\n
\n

好吧,我有一个字典,我正在尝试向同一个键添加更多值。这有可能吗?

\n
\n\n

不直接。字典的每个键始终只有一个值。使用 defaultdict 不会改变这一点。

\n\n

但是模拟每个键有多个值的字典(某些语言称为“多字典”)的常用方法是仅使用这些多个值的列表作为单个值。例如:

\n\n
>>> d = {\'a\': [0, 1, 2], \'b\': [1, 2, 3]}\n>>> d[\'a\'].append(3)\n>>> d[\'a\']\n>>> [0, 1, 2, 3]\n
Run Code Online (Sandbox Code Playgroud)\n\n

您似乎使用元组而不是列表。你可以这样做,但是,因为元组是不可变的,所以你不能调用append它们;你必须用新的更大的元组替换它们。像这样:

\n\n
>>> d = {\'a\': (0, 1, 2), \'b\': (1, 2, 3)}\n>>> d[\'a\'] = d[\'a\'] + (3,)\n>>> d[\'a\']\n>>> (0, 1, 2, 3)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这使得代码比使用列表时要复杂一些,但它是有效的。

\n\n

同时,使用 adefaultdict在这里完全无关。adefaultdict所做的就是自动处理密钥不存在的情况。例如:

\n\n
>>> d = {\'b\': (1, 2, 3)}\n>>> d[\'a\'] = d[\'a\'] + (3,)\nKeyError: \'a\'\n>>> d = defaultdict(tuple, {\'b\': (1, 2, 3)})\n>>> d[\'a\'] = d[\'a\'] + (3,)\n>>> d\n{\'b\': (1, 2, 3), \'a\': (3,)}\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

同时,您似乎正在尝试使用通常为每个键存储单个值的结构,但在您第一次需要扩展它时可以神奇地转换为多个值。在一般情况下,这是不明确的\xe2\x80\x94,无法区分恰好是元组或列表的单个值与多个值。您可以在特定情况下执行此操作,您知道您的值永远不会是集合(但请记住,字符串是字符串的集合;这会在某些时候\xe2\x80\xa6 中咬住你),或者可能是集合,但永远不会是您正在使用的特定集合类型,或者其他什么。但因为这通常不是一个好主意,Python 并没有让它变得容易。所以,你必须做这样的事情:

\n\n
def add_to_multidict(multidict, key, value):\n    if key in multidict:\n        if isinstance(multidict[key], tuple):\n            multidict[key] = multidict[key] + (value,)\n        else:\n            multidict[key] = (multidict[key], value)\n    else:\n        multidict[key] = value\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您希望能够将其作为字典上的方法调用,则需要子类化dict并编写方法来执行此操作。如果您希望能够将其作为值的方法调用,tuple则还需要子类化,并使您的 dict 子类使用元组子类。

\n\n
\n\n

最后,看起来您不仅希望使用多重字典本身来执行此操作,还希望使用多重字典存储的各个值\xe2\x80\x94换句话说,您希望每个键映射到对象的元组,这些对象本身是单个对象或对象元组。您需要编写代码来将该逻辑再推进一步;这并不难。

\n\n

如果您想将其推入无限多个步骤,那么d[\'a\'][1][2][1].append(3)您将需要递归地执行此操作:元组子类只需在扩展值时创建其自身的实例,而不是创建元组。

\n