将 for 循环转换为列表理解
Convert for loops into list comprehension
我有一个循环条件,我想将其转换为列表理解。我只想学习如何将复杂的 for 循环写成一行。
num = []
for i in range(2, numRows):
row = []
for j in range(i - 1):
row.append(sum(num[-1][j:j + 2]))
num.append([1] + row + [1])
我认为 list comprehension
只能与 if
else
条件一起使用。我们可以在里面写正则表达式吗?谁能告诉我是否可能?下面的代码对我不起作用。
row = []
[num.append([1] + row + [1]) row = [] [row.append(sum(num[-1][j:j + 2])) for j in range(i - 1)]for i in range(2, numRows)]
编辑:我的 Pascal 三角形初始代码
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
if numRows = 5
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
"""
num = [[1], [1, 1]]
if numRows == 1:
return num[0]
elif numRows == 2:
return num
row = []
for i in range(2, numRows):
for j in range(i - 1):
row.append(sum(num[-1][j:j + 2]))
num.append([1] + row + [1])
row = []
return num
您似乎在尝试制作帕斯卡三角。要使第一个代码块中的代码正常工作,您需要正确初始化 num
:
num = [[1,1]]
在列表理解中生成帕斯卡三角是不切实际的*,因为要生成每一行,您需要访问前一行。但是,结合使用 "traditional" for
循环和使用 zip
的列表组合来创建需要相加的数字对很容易。
def pascal(m):
""" Build m rows of Pascal's triangle """
row = [1]
rows = [row]
for i in xrange(m):
#Generate next row from current row
row = [x + y for x, y in zip([0] + row, row + [0])]
rows.append(row)
return rows
#test
width = 50
for row in pascal(10):
print " ".join(["%3d" % x for x in row]).center(width)
输出
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
我在您使用的列表补偿尝试中看到 row.append
。请不要那样做。 list.append
方法 returns None
,因此在列表 comp 中调用它会创建一个充满 None
的列表。当然,这是合法的 Python,并且在某些情况下,您 可能 能够以这种方式计算出所需的结果,但大多数有经验的 Python 程序员认为这是不好的练习滥用这样的列表组合。当您想要它们生成的实际列表时使用它们,而不仅仅是作为一种将 shoe-horn 一个 for
循环到一行的方法。
不要误会我的意思 - 我喜欢列表理解和生成器表达式。尽管一开始它们可能有点令人费解,但一旦您习惯了它们,它们就会简洁明了。并且列表组合比在传统的 for
循环中使用 .append
稍微更有效。然而,即使是最有经验的 Pythonista,deeply-nested/复杂的 list comps 和 gen 表达式也很难阅读。因此,不要试图在其中塞入太多内容,如果可以使代码更具可读性,请毫不犹豫地将它们分成多个阶段。
* 实际上可以使用 binomial coefficient 公式而不是加法在列表组合中生成帕斯卡三角。
我有一个循环条件,我想将其转换为列表理解。我只想学习如何将复杂的 for 循环写成一行。
num = []
for i in range(2, numRows):
row = []
for j in range(i - 1):
row.append(sum(num[-1][j:j + 2]))
num.append([1] + row + [1])
我认为 list comprehension
只能与 if
else
条件一起使用。我们可以在里面写正则表达式吗?谁能告诉我是否可能?下面的代码对我不起作用。
row = []
[num.append([1] + row + [1]) row = [] [row.append(sum(num[-1][j:j + 2])) for j in range(i - 1)]for i in range(2, numRows)]
编辑:我的 Pascal 三角形初始代码
class Solution(object):
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
if numRows = 5
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
"""
num = [[1], [1, 1]]
if numRows == 1:
return num[0]
elif numRows == 2:
return num
row = []
for i in range(2, numRows):
for j in range(i - 1):
row.append(sum(num[-1][j:j + 2]))
num.append([1] + row + [1])
row = []
return num
您似乎在尝试制作帕斯卡三角。要使第一个代码块中的代码正常工作,您需要正确初始化 num
:
num = [[1,1]]
在列表理解中生成帕斯卡三角是不切实际的*,因为要生成每一行,您需要访问前一行。但是,结合使用 "traditional" for
循环和使用 zip
的列表组合来创建需要相加的数字对很容易。
def pascal(m):
""" Build m rows of Pascal's triangle """
row = [1]
rows = [row]
for i in xrange(m):
#Generate next row from current row
row = [x + y for x, y in zip([0] + row, row + [0])]
rows.append(row)
return rows
#test
width = 50
for row in pascal(10):
print " ".join(["%3d" % x for x in row]).center(width)
输出
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
我在您使用的列表补偿尝试中看到 row.append
。请不要那样做。 list.append
方法 returns None
,因此在列表 comp 中调用它会创建一个充满 None
的列表。当然,这是合法的 Python,并且在某些情况下,您 可能 能够以这种方式计算出所需的结果,但大多数有经验的 Python 程序员认为这是不好的练习滥用这样的列表组合。当您想要它们生成的实际列表时使用它们,而不仅仅是作为一种将 shoe-horn 一个 for
循环到一行的方法。
不要误会我的意思 - 我喜欢列表理解和生成器表达式。尽管一开始它们可能有点令人费解,但一旦您习惯了它们,它们就会简洁明了。并且列表组合比在传统的 for
循环中使用 .append
稍微更有效。然而,即使是最有经验的 Pythonista,deeply-nested/复杂的 list comps 和 gen 表达式也很难阅读。因此,不要试图在其中塞入太多内容,如果可以使代码更具可读性,请毫不犹豫地将它们分成多个阶段。
* 实际上可以使用 binomial coefficient 公式而不是加法在列表组合中生成帕斯卡三角。