简体   繁体   English

汇总的Python列表理解

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM