[英]Python List Comprehension with Sum
I have some python code that looks like this: 我有一些看起来像这样的python代码:
mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
for i in range(1,3):
nwalls = [sum(nwalls[k] for k in mat[j]) for j in range(5)]
# nwalls = [1, 2, 2, 1, 2]
I can't for the life of me unroll this into syntax without using list comprehension for me to understand. 我无法一生都在不使用列表理解的情况下将其展开为语法。 Please assist.
请协助。
The direct translation would be 直接翻译将是
mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
for i in range(1, 3):
_nwalls = []
for j in range(5):
tot = 0 # - sum
for k in mat[j]: # /
tot += nwalls[k] # /
_nwalls.append(tot)
nwalls = _nwalls
(nwalls[k] for k in mat[j])
it self is a generator, in python repl, you can check it as: (nwalls[k] for k in mat[j])
它本身是一个生成器,在python repl中,您可以将其检查为:
>>> y = (x for x in range(10))
>>> type(y)
<class 'generator'>
and sum
can take a generator, as sum( (x for x in range(10)) )
, and as PEP289 said 和
sum
可以使用一个生成器,如sum( (x for x in range(10)) )
和PEP289表示
if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.
如果函数调用具有单个位置参数,则它可以是不带括号的生成器表达式,但是在所有其他情况下,都必须将其括在括号中。
so it looks like sum(x for x in range(10))
所以它看起来像
sum(x for x in range(10))
instead of recreating the nwalls
list every time just assign a new value to the specific slot in the list, just keep a record of the previous values in the list so that you do not end up using the value generated earlier in the loop: 不必每次都重新创建
nwalls
列表,只需为列表中的特定插槽分配一个新值,而只需在列表中保留以前的值,这样您就不会最终使用循环中先前生成的值:
mat = [[3], [4], [4], [0], [1, 2]]
nwalls = 5*[1]
prev_nwalls = 5*[1]
for _ in range(1,3):
for j in range(5):
nwalls[j] = sum(prev_nwalls[k] for k in mat[j])
prev_nwalls[:] = nwalls
assert nwalls == [1, 2, 2, 1, 2]
If you want to avoid comprehension completely first know that the python equivelent to the sum
builtin looks something like this: 如果您想完全避免理解,请首先知道等价于内置
sum
的python如下所示:
def sum(iterable):
s = 0
for n in iterable:
s+=n
return s
So the line nwalls[j] = sum(prev_nwalls[k] for k in mat[j])
would be replaced with something like: 因此,将行
nwalls[j] = sum(prev_nwalls[k] for k in mat[j])
替换为:
s = 0
for k in mat[j]:
s+=nwalls[k]
nwalls[j] = s
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.