我可以直接使用字典本身内的 for 循环在字典中定义值吗?
Can I define a value in a dictionary directly using a for loop within the dictionary itself?
我正在处理一些 Project Euler 问题,并且有一个解决方案,我想使其更具适应性。问题本身在这里并不重要,但是对于那些好奇的人来说,这是问题 11.
目前,我有一个 20 x 20 整数值的网格,我正在寻找 4 个相邻值的最大乘积。一切都很好,而且很快。我目前拥有的是:
maxi = 0
amount = 4
for i in range (0,len(grid) - amount):
for j in range (0,len(grid) - amount):
try:
max_dic = {
'right':grid[i][j]*grid[i][j+1]*grid[i][j+2]*grid[i][j+3],
'down':grid[i][j]*grid[i+1][j]*grid[i+2][j]*grid[i+3][j],
'down_right':grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3],
'down_left':grid[i][j]*grid[i+1][j-1]*grid[i+2][j-2]*grid[i+3][j-3]
}
except IndexError:
pass
max_key = str(max(max_dic.items(), key=operator.itemgetter(1))[0])
if max_dic[max_key] > maxi:
maxi = max_dic[max_key]
我想做的是用我可以改变的东西替换字典中的值(所以就数量而言)我想使用一个 for 循环从 0 到 amount-1 看起来像这样:
'right': for a in range(amount): # Multiply the correct values
但是,我不确定这是否可行,如果可行,如何实现。
关于如何执行此操作的任何建议?
你可以这样写
import numpy as np
...
'right': np.prod([grid[i][j] for j in range(i, i + amount)])
在您当前的实施中,您根本不会得到 max_dic
结果
任何部分超出网格边界。经常遇到这样的问题,你
确实想要部分结果。如果是这样,你可能想要
以更细粒度的方式处理 IndexError
的能力。例如,
你可以创建一个简单的辅助函数,它接受一个网格和两个索引,并且
returns 值或一些默认值(在乘法的情况下为 1
)。
def get_val(grid, i, j, default = 1):
try:
return grid[i][j]
except IndexError:
return default
一旦你有了这个构建基块,接下来就是准备一些列表了
索引,然后使用标准库中的一些函数:
from operator import mul
from functools import reduce
# Inside your two loops over i and j ...
ms = list(range(i, i + amount))
ns = list(range(j, j + amount))
rns = list(range(j, j - amount, -1))
max_dic = {
'right' : reduce(mul, [get_val(grid, i, n) for n in ns]),
'down' : reduce(mul, [get_val(grid, m, j) for m in ns]),
'down_right' : reduce(mul, [get_val(grid, m, n) for m, n in zip(ms, ns)]),
'down_left' : reduce(mul, [get_val(grid, m, n) for m, n in zip(ms, rns)]),
}
我正在处理一些 Project Euler 问题,并且有一个解决方案,我想使其更具适应性。问题本身在这里并不重要,但是对于那些好奇的人来说,这是问题 11.
目前,我有一个 20 x 20 整数值的网格,我正在寻找 4 个相邻值的最大乘积。一切都很好,而且很快。我目前拥有的是:
maxi = 0
amount = 4
for i in range (0,len(grid) - amount):
for j in range (0,len(grid) - amount):
try:
max_dic = {
'right':grid[i][j]*grid[i][j+1]*grid[i][j+2]*grid[i][j+3],
'down':grid[i][j]*grid[i+1][j]*grid[i+2][j]*grid[i+3][j],
'down_right':grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3],
'down_left':grid[i][j]*grid[i+1][j-1]*grid[i+2][j-2]*grid[i+3][j-3]
}
except IndexError:
pass
max_key = str(max(max_dic.items(), key=operator.itemgetter(1))[0])
if max_dic[max_key] > maxi:
maxi = max_dic[max_key]
我想做的是用我可以改变的东西替换字典中的值(所以就数量而言)我想使用一个 for 循环从 0 到 amount-1 看起来像这样:
'right': for a in range(amount): # Multiply the correct values
但是,我不确定这是否可行,如果可行,如何实现。
关于如何执行此操作的任何建议?
你可以这样写
import numpy as np
...
'right': np.prod([grid[i][j] for j in range(i, i + amount)])
在您当前的实施中,您根本不会得到 max_dic
结果
任何部分超出网格边界。经常遇到这样的问题,你
确实想要部分结果。如果是这样,你可能想要
以更细粒度的方式处理 IndexError
的能力。例如,
你可以创建一个简单的辅助函数,它接受一个网格和两个索引,并且
returns 值或一些默认值(在乘法的情况下为 1
)。
def get_val(grid, i, j, default = 1):
try:
return grid[i][j]
except IndexError:
return default
一旦你有了这个构建基块,接下来就是准备一些列表了 索引,然后使用标准库中的一些函数:
from operator import mul
from functools import reduce
# Inside your two loops over i and j ...
ms = list(range(i, i + amount))
ns = list(range(j, j + amount))
rns = list(range(j, j - amount, -1))
max_dic = {
'right' : reduce(mul, [get_val(grid, i, n) for n in ns]),
'down' : reduce(mul, [get_val(grid, m, j) for m in ns]),
'down_right' : reduce(mul, [get_val(grid, m, n) for m, n in zip(ms, ns)]),
'down_left' : reduce(mul, [get_val(grid, m, n) for m, n in zip(ms, rns)]),
}