有什么办法做这样的事
dict = {
'a':1,
'b':dict['a']+1,
}
还是我必须先在其他地方创建值,然后再创建字典。
答案 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}
如果增量是自定义的,则可以将accumulate与add结合使用:
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'])