-1

I'm a newer to Python and I'm learning it.

Here I want to use a generator to output the Pascal's Triangle. I'd like to get the output like this

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]

And what I wrote is

# Pascal's Triangle
def triangles() :
    result = [1]
    while True :
        # if i use yield result, the output will be [1, 0], [1, 1, 0] ...
        yield result[:]
        result.append(0)
        result = [result[i]+result[i-1] for i in range(len(result))]

# make a list of the triangles. 
n = 0
results = []
for t in triangles():
    results.append(t)
    n = n + 1
    if n == 5:
        break

for t in results:
    print(t)

This code works well. However when I change yield result[:] to yield result, the output is

[1, 0]
[1, 1, 0]
[1, 2, 1, 0]
[1, 3, 3, 1, 0]
[1, 4, 6, 4, 1]

After debugging the code, I found that the iteration variable t changed to [1, 0] after running

result.append(0)

the first time, but there isn't any words like return or yield.

Why could that happen?


Update Question

I made a minimal working example here

def func():
    a = [1, 2]
    while True :
        yield a
        a.append(0)

# # PM 1 (Print Method 1)
# n = 0
# results = []
# b = func()
# for t in b:
#     results.append(t)
#     n = n + 1
#     if n == 3:
#         break

# for t in results:
#     print(t)

# PM 2
b = func()
counter = 0
for i in b :
    print(i)
    counter += 1
    if counter == 3:
        break

When I use PM 1 to print the list, I got

[1, 2, 0, 0]
[1, 2, 0, 0]
[1, 2, 0, 0]

When I use PM 2 to print the list, I got

[1, 2]
[1, 2, 0]
[1, 2, 0, 0]

So I think the problem occurs at how I print the list.

Syvshc
  • 141
  • 4
  • 1
    Did you read up what the `[:]` does before asking the question? – user202729 Feb 24 '21 at 04:58
  • Or is it too hard to search for? There you go https://stackoverflow.com/questions/509211/understanding-slice-notation – user202729 Feb 24 '21 at 04:58
  • Although you did try to debug it. – user202729 Feb 24 '21 at 04:59
  • 1
    `result[:]` creates a copy of `result` to `yield`. If you don't make a copy, then the `.append(0)` right afterward shows up in the result like you're seeing. – rdas Feb 24 '21 at 04:59
  • 1
    @rdas Well, I understand what you said. However in my mind, `yield` happened before the variable `result` changed, I mean that when python saw `yield result` first time, `t` got `[1]`, and then `result.append(0)` works. I think I should get a `[1]` at least in the `results`, but I didn't. – Syvshc Feb 24 '21 at 05:05
  • But it's the same object so it gets modified afterwards – rdas Feb 24 '21 at 05:13
  • @rdas I made a minimal working example, and I found that if I save the generator in a list and print it together, the problem happens. When I print it in the iterator straight, there is no problem. – Syvshc Feb 24 '21 at 05:44
  • I think I have already understood. > But it's the same object so it gets modified afterwards If I don't make a copy, `t` and `results[0]` points to `result`'s address (is this right?) and when the value in 'result''s address changes, all the value in 't' and 'results[0]` change together. – Syvshc Feb 24 '21 at 05:56

1 Answers1

0

I am sure what is the direction of your work, whether it just for print or more. But, below should give you a general overview about tril_indices

import  numpy as np

# Pascal's Triangle
def triangles() :
    result = [1]
    while True :
        # if i use yield result, the output will be [1, 0], [1, 1, 0] ...
        yield result[:]
        result.append(0)
        result = [result[i]+result[i-1] for i in range(len(result))]

# make a list of the triangles.
n = 0
results = []
for t in triangles():
    results.extend(t)
    n = n + 1
    if n == 5:
        break


res_arr=np.array(results)
t,b = np.tril_indices(6, -1)

idx_pair = np.tril_indices(6, -1)
this_con = np.zeros ( (6, 6) )
this_con [idx_pair] = res_arr
print(this_con)
mpx
  • 3,081
  • 2
  • 26
  • 56