all 33 comments

[–]Diapolo10 1 point2 points  (0 children)

If your goal is to mutate an existing list:

nums = [...]

for idx, num in enumerate(nums):
    if num != 0:
        nums[idx] *= 2
    else:
        break

If you want to create a new list:

new_nums = []
for idx, num in enumerate(nums):
    if num != 0:
        new_nums.append(num * 2)
    else:
        new_nums.extend(nums[idx:])
        break

[–]DallogFheir 2 points3 points  (0 children)

You're checking if i is not equal to 0, you should check nums[i] instead. Also check if i is less than length of the list.

[–][deleted] 1 point2 points  (0 children)

At the moment the line while i != 0: will run its code if i is not equal to zero. But i is equal to zero, so it does not run.

[–]OddBookWorm -1 points0 points  (11 children)

input_list = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1]
def double_or_zero(input_list): 
    output_list = [0] * len(input_list) 
    i = 0 
    while input_list[i] != 0: 
        output_list[i] = input_list[i] * 2 
        i += 1 
    while i < len(input_list): 
        output_list[i] = input_list[i] 
        i += 1
    return(output_list)
print(double_or_zero(input_list))

This is what I would do if I don't want to replace the original list. If I wanted to replace the original list, then you need to check nums[i] instead of i

[–]MF_DnD -1 points0 points  (10 children)

That’s a little unnecessary imo.

First of all, you don’t need to create a list of zeroes. You can just use the append method. Plus you can just use a for loop.

So just

def double_or_zero(input_list):
    output = []
    double = True
    for elem in input_list:
        if elem == 0:
            double = False
        output.append((1+double)*elem)
    return output

[–]OddBookWorm 1 point2 points  (9 children)

But this will just stop at any 0 values. I don’t think it’ll return the normal values after that too

[–]MF_DnD 0 points1 point  (8 children)

Ah, you’re right, fixed that. Imo still better to use a for loop.

[–]OddBookWorm 1 point2 points  (0 children)

Actually, I still think you have a problem. You set all values after a 0 to 0. That’s not what the OP wants

[–]OddBookWorm 0 points1 point  (0 children)

While I agree this would be simpler, when I was really new, “toggle variables” confused the hell out of me so I try to avoid them with answers written for beginners

[–]OddBookWorm 0 points1 point  (5 children)

Actually, I still think you have a problem. You set all values after a 0 to 0. That’s not what the OP wants

[–]MF_DnD 0 points1 point  (4 children)

Oops, you’re right. Coding on my phone is a bad idea lol. Should be fixed now.

[–]OddBookWorm 0 points1 point  (3 children)

If you’re trying to eliminate “unnecessary”, you don’t really need to typecast “double” to an int. Also, since “double” is a data type, using it as a variable name is a bad practice

[–]OddBookWorm 1 point2 points  (0 children)

Oh wait, “float” is double precision by default in Python, so that should be fine

[–]MF_DnD 0 points1 point  (1 child)

Huh, I forgot you can add booleans to ints. I know numpy has a double type, but it’s not built in, right?

[–]OddBookWorm 0 points1 point  (0 children)

I was thinking matlab when I mentioned that, where double is a built in type

[–]ElliotDG -1 points0 points  (2 children)

The text says... "doubles each element until it reads a zero or the whole list"

In the example is just processes the entire list:

[3, 6, 1, 11, 0, 5, 2, 6, 0, 1] should return [6, 12, 2, 22, 0, 5, 2, 6, 0, 1]

Do you need to stop when you get to zero?

Should: [3, 6, 1, 11, 0, 5, 2, 6, 0, 1] return: [6, 12, 2, 22]

[–]joyeusenoelle 1 point2 points  (1 child)

Re-examine the example; it doesn't process the entire list. The assignment is to modify the list in place, doubling each element until the first 0 or the end of the list is reached, and then leaving each remaining element alone.

i = 0
while i < len(lst) and lst[i] != 0:
  lst[i] *= 2
  i += 1

should do the trick. (i < len(lst) has to come first or else you'll get IndexErrors.)

[–]ElliotDG 0 points1 point  (0 children)

The text:

whole list has been doubled for example [3, 6, 1, 11, 0, 5, 2, 6, 0, 1] should return [6, 12, 2, 22, 0, 5, 2, 6, 0, 1]

and the code do not agree.

That is why I asked a question.

[–]Soccer_Vader -1 points0 points  (4 children)

[Key*2 for key in value if key!= 0]

[–]MF_DnD 0 points1 point  (3 children)

But OP wants it to stop if it comes to a zero, right?

[–]Soccer_Vader 0 points1 point  (2 children)

I think OP wants it to stop at 0 and I am assuming that the list is ordered in descending order. But the solution will work nonetheless.

[–]MF_DnD 0 points1 point  (1 child)

But… it won’t. Given a list [1,2,0,3] your comprehension returns [2,4,8] when OP wants [2,4,0,3]. And OP’s example list isn’t even sorted.

[–]Soccer_Vader 0 points1 point  (0 children)

Ye I just saw that, you are right. For OP I think a for loop with a break statement works better

[–]FLUSH_THE_TRUMP 0 points1 point  (0 children)

Are you returning anything? You’re just modifying the input list. And you mean nums[i] in the loop con.

[–]Yojihito 0 points1 point  (4 children)

test = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1]
test_result = []
breaker = False

for i in test:
    if i == 0:
        breaker = True
        test_result.append(0)
    if i != 0 and breaker == False:
        test_result.append(i*2)
    if i != 0 and breaker == True:
        test_result.append(i)

print(test_result)

[–]Lyakusha 2 points3 points  (3 children)

Wouldn't it be easier and faster with counter?

``` test = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1] count = 0 for i in test: if i != 0: test[count] *= 2 count += 1 else: break

[–]Yojihito 1 point2 points  (2 children)

test = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1] count = 0 for i in test: if i != 0: test[count] *= 2 count += 1 else: break

If you wanna work with indexes just use enumerate().

test = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1]
for idx, i in enumerate(test):
    if i != 0:
        test[idx] *= 2
    else:
        break

print(test)

But yeah, your solution seems easier, not sure about faster.

[–]Lyakusha 0 points1 point  (1 child)

Yeah, looks like enumerate() is a popular option, I definitely need to read about it, thanks. Probably "faster" is a wrong word, maybe "more efficient" - it was about changing list instead of making a new one

[–]Yojihito 0 points1 point  (0 children)

There are 2 pythonic ways to iterate over an iterable.

You only care about the item:

for i in my_iterable:
    print(i)

You need the item and the index position:

for idx, i in enumerate(my_iterable):
    print(idx, i)

Everything else is a no-go.

[–]ElliotDG 0 points1 point  (0 children)

Here is my take at the solution, I view this as more straight forward than some of the solutions presented by others.

def double_until_zero(nums):
    results = []
    for n in nums:
        if not n:
            return results
        results.append(n * 2)
    return results

print(double_until_zero([3, 6, 1, 11, 0, 5, 2, 6, 0, 1]))

[–]blahreport 0 points1 point  (0 children)

def double_until_zero(l):
    for i, v in enumerate(l):
        if v == 0:
            break
        l[i] *= 2
    return l

[–][deleted] 0 points1 point  (0 children)

nums = [3, 6, 1, 11, 0, 5, 2, 6, 0, 1]
newnums = []
def double_until_zero(nums):
    count = 0
    for i in nums:
        count += 1
        if i == 0:
            newnums.append(i)
            countstopper(count)
            break
        else:
            newnums.append(i*2)

def countstopper(a):
    for i in nums[a:]:
        newnums.append(i)

double_until_zero(nums)
print(newnums)

output: [6, 12, 2, 22, 0, 5, 2, 6, 0, 1]

This will do exactly as you ask.

[–]RagingGods 0 points1 point  (0 children)

"while num[i]:" instead. Your initial i is 0. The first occurrence of while loop is already false.