Python中普通for循环与列表推导式的区别及代码改写问题
First, let's recap the original Pascal's Triangle generation code we're discussing:
def generate(numRows): pascal = [[1]*(i+1) for i in range(numRows)] for i in range(numRows): for j in range(1,i): pascal[i][j] = pascal[i-1][j-1] + pascal[i-1][j] return pascal
Key Differences Between the Two Approaches
List Comprehension Version: The line
[[1]*(i+1) for i in range(numRows)]creates a complete 2D list in one step. It iterates through everyifrom 0 tonumRows-1, generates a row ofi+1ones for each iteration, and collects all these rows into a single list assigned topascal. By the end of this line,pascalalready contains every row of the triangle (all filled with ones), ready to be updated with the correct values.Broken Basic Loop Version: The code
for i in range(numRows): pascal = [[1]*(i+1)]has a critical flaw: it overwrites the entirepascalvariable on every loop iteration. Instead of building up a list of rows, each loop replacespascalwith a brand-new list that only holds the current row (e.g., wheni=2,pascalbecomes[[1,1,1]], discarding the rows created fori=0andi=1). By the end of the loop,pascalwill only contain the last row of the triangle.
How to Fix the Basic Loop to Match the List Comprehension
To make the basic loop behave identically to the list comprehension, you need to build the 2D list incrementally instead of overwriting it. Here's the corrected approach:
- Start with an empty list to hold all rows of the triangle.
- For each
i, create the row ofi+1ones and append it to the list, rather than replacing the entire list.
The fixed loop code looks like this:
pascal = [] # Initialize empty list to collect rows for i in range(numRows): pascal.append([1]*(i+1)) # Add each new row to the list instead of overwriting
After running this loop, pascal will be exactly the same as the one created by the original list comprehension. You can then run the nested loop to fill in the middle values just like in the original code.
内容的提问来源于stack exchange,提问作者SuperGuy10

