Malfet
Malfet

Reputation: 1780

Iteration through list with for

I'm quite a newbie in Python. Imagine I have a list [100, 200, 300, 301, 315, 345, 500]. I want to create a new list out of it, like [100, 200, 300, 500].

When I iterate through the list like that:

for i in range(len(list)):
    while (list[i+1] - 100) <= list[i]:
        i = i + 1
        k = list[i]

Then changes of i within while loop are not reflected for i within for loop, so I iterate multiple times through the same elements.

What would be the better way to change the code to avoid that?

Upvotes: 0

Views: 305

Answers (3)

Eastsun
Eastsun

Reputation: 18859

Here is my solution:

def my_filter(xs):
    ys = []
    for x in xs:
        if (not ys) or ys[-1] + 100 <= x:
            ys.append(x)
    return ys
my_filter([100, 200, 300, 301, 315, 345, 500])  >> [100, 200, 300, 500]

Upvotes: 0

Lauritz V. Thaulow
Lauritz V. Thaulow

Reputation: 50985

Here's how I'd do it

>>> mylist = [100,200,300,301,315,345,500]
>>> [x for x in mylist if x % 100 == 0]
[100, 200, 300, 500]

EDIT: On closer inspection of your algorithm, it seems you're actually trying to build a list of the values that are larger than the previous value plus 99. In that case, this will work:

def my_filter(lst):
    ret = [lst[0]]
    for i1, i2 in zip(lst, lst[1:]):
        if i2 - i1 >= 100:
            ret.append(i2)
    return ret

The above algorithm works like this:

>>> my_filter([101, 202, 303, 305, 404, 505])
[101, 202, 303, 505]

Upvotes: 5

poke
poke

Reputation: 387557

range(len(list)) will look at the list length once and then create a range-iterator out of it which is then completely separated from both the list and its length.

So for i in range(len(list)) will make i go from 0 to len(list)-1, without respecting changes of the list. Also note that updating the iterator variable i within the loop will not affect the loop itself at all. When the next iteration starts, i will just get the next value, regardless of if you wanted to skip an interation by incrementing i before.

To skip iterations you usually use the continue statement, which will just abort the current iteration and start with the next i.

In respect of your actual problem, you seem to want to filter all numbers which are multiples of 100. You can check that for a single number much easier by checking if you can divide it by 100 without any remainders. For this you use the modulo operation, which will give you the remainder for a division. Combined with a list comprehension in which you filter for those, you can write it simply like this:

>>> lst = [100, 200, 300, 301, 315, 345, 500]
>>> [n for n in lst if n % 100 == 0]
[100, 200, 300, 500]

Also note that you shouldn’t name your variables list as that will overwrite the reference to the list type.

Upvotes: 1

Related Questions