Python-在字典中使用先前的值

时间:2018-11-05 16:27:01

标签: python dictionary

有什么办法做这样的事

dict = {
    'a':1,
    'b':dict['a']+1,
}

还是我必须先在其他地方创建值,然后再创建字典。

4 个答案:

答案 0 :(得分:4)

您的代码将无法正常工作,因为dict变量(顺便说一句,内置了dict函数的阴影)尚未在{{ 1}}文字已经过评估,因此不能在{...}中使用。

相反,您可以创建数字的可迭代项,例如使用{...}或仅使用itertools.count,然后从该可迭代对象中获取iter(range(1, some_number))的值。

next

或者将>>> nums = itertools.count(1) >>> {"a": next(nums), "b": next(nums), "c": next(nums)} {'a': 1, 'b': 2, 'c': 3} 函数与dict结合使用,以组合键列表及其值:

zip

(这也适用于>>> dict(zip(("a", "b", "c"), itertools.count(1))) {'a': 1, 'b': 2, 'c': 3} 以外的步骤,或者实际上适用于任意值列表,而不仅仅是数字。在步骤始终为1的情况下,enumerate可能确实是更简单的选择。)

答案 1 :(得分:3)

如果增量始终 1,则可以使用枚举:

keys = ['a', 'b', 'c']
result = {k: i for i, k in enumerate(keys, 1)}
print(result)

输出

{'b': 2, 'c': 3, 'a': 1}

如果增量是自定义的,则可以将accumulateadd结合使用:

from itertools import accumulate
from operator import add

keys = ['a', 'b', 'c']
increments = [1, 2, 7]

result = {k: v for k, v in zip(keys, accumulate(increments, add))}
print(result)

请注意,递增的第一个值对应于第一个键的值。

更新

如@tobias_k所述,您可以使用累加而不传递add

result = {k: v for k, v in zip(keys, accumulate(increments))}

答案 2 :(得分:1)

这是一个相当愚蠢的方法。在字符串中定义dict文字,然后使用ast.parse获取定义其键和值的每个表达式的值。然后,您可以依次评估每个对象,为locals提供一个自定义的eval参数,以便在仍在创建字典时强制使字典对象可访问。

import ast

def eval_self_referential_dict_literal(s, locals = None):
    """
    Evaluates a string containing a dict literal.
    Capable of resolving keys and values that are present higher up in the literal. Use `d` to refer to the dict itself.
    Provide a mapping to the `locals` parameter if you need to access other names in the literal. You might pass in `locals()`, for example.
    """

    expr = ast.parse(d, mode='eval')
    assert isinstance(expr, ast.Expression)
    dict_node = expr.body
    assert isinstance(dict_node, ast.Dict)

    result = {}
    if locals is None:
        locals = {}
    else:
        locals = locals.copy()
    locals['d'] = result

    for key_node, value_node in zip(dict_node.keys, dict_node.values):
        key = eval(compile(ast.Expression(key_node), '', mode='eval'), globals(), locals)
        value = eval(compile(ast.Expression(value_node), '', mode='eval'), globals(), locals)
        result[key] = value
    return result

d = """
{
    'a':1,
    'b':d['a']+1,
    d['b']: d['a'],
    x: 99
}
"""

x = "blah"

print(eval_self_referential_dict_literal(d, locals()))

结果:

{'a': 1, 'b': 2, 2: 1, 'blah': 99}

答案 3 :(得分:0)

通常情况下,人们会使用defaultict

d = defaultdict(lambda: 1, {"a": 0})

但是可以有更多有趣的定义:

from collections import defaultdict
import itertools

d = defaultdict(itertools.count().__next__)
print (d['a'], d['b'])