我试图创建一个类似于此的字典(部分示例):
{(1, 1): 'Residential', (2, 1): 'Residential', (3, 1): 'Residential', (1, 2): 'Crafts', (2, 2): 'Crafts', (3, 2): 'Crafts', (4, 1): 'Law, Government', (5, 1): 'Law, Government', (4, 2): 'Public Space', (5, 2): 'Public Space', (6, 1): 'Vice', (6, 2): 'Entertainment'}
对于一些更聪明的解决方案而言似乎是一个问题的关键逻辑是,一组值分布在3个键上,另一组分布在2个键上,第三组分别有一个键。
我不是多次编写副本,而是以某种理解方式以编程方式创建它。
USE = dict([(n, 1), "Residential"] for n in range(1, 4))
这很有用,例如,创建它的第一部分。我能做到:
USE2 = dict([(n, 2), "Crafts"] for n in range(1, 4))
USE.update(USE2)
对于常数而言,这是一种混乱,不优雅和糟糕的风格。
我对任何其他策略都感到茫然。
我尝试过某种形式的连续理解:
USE = dict([(n, 1), "Residential"] for n in range(1, 4),
[(n, 2), "Crafts"] for n in range(1, 4),...
但这失败了,因为dict()不会占用多个参数。
我无法Python 3 unpacking generalizations:
USE = dict(**dict([(n, 1), "Residential"] for n in range(1, 4)),
**dict([(n, 2), "Crafts"] for n in range(1, 4)),...
因为我不明白这种风格仅限于字符串。使用字符串需要稍后转换将用于引用字典的随机数,并且看起来更令人头疼(尽管我认为这取决于是否有一个优雅的解决方案)。
而dict comprehension看起来不够强大(此处的完整数据:前6位是最后6位的3倍):
space = ["Residential", "Crafts", "Labor", "Shops", "Trade", "Hospitality",
"Law, Government", "Public Space", "Power", "Manufacture", "Transportation", "Leisure",
"Vice", "Entertainment", "Storage", "Cultivation", "Academic", "Artists"]
TRY = {(y, x+1): s for x, s in enumerate(space) for y in range(1, 7)}
由于列表大小,这最终会留下我的6x6界限。如果我模x,它最终会覆盖条目。似乎我必须编写一个专门的函数来覆盖奇怪的3/2/1重复,这对于通过某种理解应该是可能的是不必要的。
有没有办法在一行中声明具有这种复杂性的字典?如果不是,那么宣布这种常数的正确方式是什么?
答案 0 :(得分:1)
俗话说:
不要编写程序,编写编写程序的程序。
我建议的是启动一个交互式会话(或IPython),创建部分dicts并使用update
来合并它们。
然后打印出合并后的dict
并将其粘贴到您的源代码中。
答案 1 :(得分:1)
您描述的2D结构实际上非常适合numpy数组:
>>> import numpy as np
>>>
>>> space = ["Residential", "Crafts", "Labor", "Shops", "Trade", "Hospitality",
... "Law, Government", "Public Space", "Power", "Manufacture", "Transportation", "Leisure",
... "Vice", "Entertainment", "Storage", "Cultivation", "Academic", "Artists"]
>>>
>>> sparr = np.array(space, dtype=object).reshape(3,6).repeat((3,2,1), axis=0)
请注意这条线的自然程度如何:制作一个数组,重塑为3行,每行6列,垂直重复(轴0)第一个元素3次,第二个元素两次,最后一次。
结果:
>>> sparr
array([['Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
['Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
['Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
['Law, Government', 'Public Space', 'Power', 'Manufacture', 'Transportation', 'Leisure'],
['Law, Government', 'Public Space', 'Power', 'Manufacture', 'Transportation', 'Leisure'],
['Vice', 'Entertainment', 'Storage', 'Cultivation', 'Academic', 'Artists']], dtype=object)
这几乎是正确的,只有索引是从零开始的,所以我们需要添加一个虚拟列和一个虚拟行:
result = np.full((7, 7), None, dtype=object)
>>> result[1:, 1:] = sparr
>>>
>>> result
array([[None, None, None, None, None, None, None],
[None, 'Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
[None, 'Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
[None, 'Residential', 'Crafts', 'Labor', 'Shops', 'Trade', 'Hospitality'],
[None, 'Law, Government', 'Public Space', 'Power', 'Manufacture', 'Transportation', 'Leisure'],
[None, 'Law, Government', 'Public Space', 'Power', 'Manufacture', 'Transportation', 'Leisure'],
[None, 'Vice', 'Entertainment', 'Storage', 'Cultivation', 'Academic', 'Artists']], dtype=object)
现在,这是" duck" - 等同于你的字典,查找方式。例如:
>>> result[2,1] # result[(2,1)] also works
'Residential'
答案 2 :(得分:0)
如果您正在寻找单线理解,那么这样的事情怎么样?
a = (3,'Residential',3,'Crafts',2,'Law, Government',2,'Public Space',1,'Vice',1,'Entertainment')
use = dict()
use.update(dict([(n / 2 + 1, s), a[n+1]] for s in range(1, 4) for n in range(0, len(a), 2) ))
答案 3 :(得分:0)
这个关键方案有点神秘。这是一种缩小它的方法。设(n0,n1)是给定类别名称的键。对于每个名称,n1是常量,但是n0涵盖了一个连续的范围,因此我们可以只存储该范围的第一个和最后一个项目。然后我们使用带有双for
循环的字典理解将浓缩版本扩展为您真正想要的字典。
# Condensed key table.
# Each name in the full table has a 2-tuple key (n0, n1)
# The tuples in `table` are (first_n0, last_n0, n1)
table = {
'Residential': (1, 3, 1),
'Crafts': (1, 3, 2),
'Law, Government': (4, 5, 1),
'Public Space': (4, 5, 2),
'Vice': (6, 6, 1),
'Entertainment': (6, 6, 2),
}
out = {(n0, n1): name for name, (first, last, n1) in table.items()
for n0 in range(first, last + 1)
}
for k, v in out.items():
print(f'{k}: {v!r},')
<强>退出
(1, 1): 'Residential',
(2, 1): 'Residential',
(3, 1): 'Residential',
(1, 2): 'Crafts',
(2, 2): 'Crafts',
(3, 2): 'Crafts',
(4, 1): 'Law, Government',
(5, 1): 'Law, Government',
(4, 2): 'Public Space',
(5, 2): 'Public Space',
(6, 1): 'Vice',
(6, 2): 'Entertainment',
这里使用传统的for
循环相当于那个dict comp。您可能会发现此版本更具可读性。
out = {}
for name, (first, last, n1) in table.items():
for n0 in range(first, last + 1):
out[n0, n1] = name