Using List Comprehension for a number sequence (1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1 …..) in Python

Question:

I’m doing exercise questions from A Practical Introduction to Python Programming by Brian Heinold (pg 83) and there was a simpler question:

  1. Using a for loop, create the list below, which consists of ones separated by increasingly many
    zeroes. The last two ones in the list should be separated by ten zeroes.
    [1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,….]
# Question 11
L = [1]
for i in range(11):
  if i == 0:
    L.append(1)
  else:
    for j in range(i):
      L.append(0)
    L.append(1)
print(L)
  1. Use a list comprehension to create the list below, which consists of ones separated by increasingly many zeroes. The last two ones in the list should be separated by ten zeroes.
    [1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,1,….]

I’m having difficulty with converting it into one line using list comprehension. Best I could do was

# Question 15
L = [[1, [0]*i] for i in range(11)]
print(L)
L = [j for row in L for j in row]
print(L)

Which would print:

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

Flattening the list any further would result in a TypeError: ‘int’ object is not iterable and I would have to add another 1 at the end of the list using a seperate command which I guess would be fine. To add the code for flattening the list kinda goes over my head.

This is a second attempt using if/else statements, that gives the produces the same output and gives the same TypeError for when I try to flatten it completely.

L = [1 if i%2 == 0 else [0]*(i//2) for i in range(22)]
L = [j for row in L for j in row]
print(L)

I just want this as output:

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

Thanks!

Asked By: Waleed Malik

||

Answers:

You can solve it like this:

L = [j for i in range(11) for j in [1, *([0]*i)]]

or

L = [j for i in range(11) for j in [1, *(0 for k in range(i))]]

Edit
I missed that it should end with a one. Here’s a solution that does that:

L = [1, *(j for i in range(11) for j in [*(0 for k in range(i)), 1])]

or with list comprehension instead of generators:

L = [1, *[j for i in range(11) for j in [*[0 for k in range(i)], 1]]]
Answered By: md2perpe

I know it’s not allowed in the problem, but assume we can use math library, there’s a really interesting solution that goes like this:

from math import sqrt, floor

print([1] + [1 * ((-1+sqrt(1+8*i))/2 > 0 and floor((-1+sqrt(1+8*i))/2) == (-1+sqrt(1+8*i))/2 or (-1-sqrt(1+8*i))/2 > 0 and floor((-1-sqrt(1+8*i))/2) == (-1-sqrt(1+8*i))/2) for i in range(1, 67)])

The key observation is that all ones in the target list has an index that’s a triangular number except for the one on index 0(no pun intended). So we can just check if the current index is a triangular number.

The nth triangular number can be expressed as:

Expression for the nth triangular number

Let i be the current index we are checking. All we need to do is to solve:

enter image description here

And check if one of the roots is a natural number.

Again, I know this is not a valid answer. I just want to show it as the idea is interesting.

Answered By: AlpacaMax

You could use a nested comprehension that produces an increasing number of values that you convert to 0s and 1s by returning 0s for all but the last of each group:

n = 10
r = [1]+[b//z for z in range(1,n+2) for b in range(1,z+1)]
print(r)
[1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

If you want to avoid the need to add the initial [1], you could use a similar approach starting z at -1 instead of 1:

r = [ 1-(b<z) for z in range(-1,n+1) for b in range(z+1 or 1)] 
Answered By: Alain T.

p=[]

for i in range(11):

p.append(1)

for j in range(i):

    p.append(i*0)

print(p)

Answered By: ANSIKA JAISWAL
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.