Daniel H
Daniel H

Reputation: 399

changing values in a list while looping through it?

I've done some searches, but I'm actually not sure of the way to word what I want to take place, so I started a question. I'm sure its been covered before, so my apologies.

The code below doesn't work, but hopefully it illustrates what I'm trying to do.

sieve[i*2::i] *= ((i-1) / i):

I want to take a list and go through each item in the list that is a multiple of "i" and change its value by multiplying by the same amount.

So for example if I had a list

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

and I want to start at 2 and change every 2nd item in the list, by itself * (2 - 1 ) / 2. So after it would look like

[1, 2, 3, 2, 5, 3, 7, 4, 9, 5]

how do I do that pythonically?

thank you very much!

EDIT to add:

sorry, I see where my poor wording has caused some confusion (ive changed it in the above).

I dont want to change every multiple of 2, I want to change every second item in the list, even if its not a multiple of 2. So I cant use x % 2 == 0. Sorry!

Upvotes: 0

Views: 1122

Answers (5)

dawg
dawg

Reputation: 103714

You can use Python's extended slicing and slice assignment to do that:

>>> li=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> li[3::2]=[x/2 for x in li[3::2]]
>>> li
[1, 2, 3, 2, 5, 3, 7, 4, 9, 5]

Upvotes: 2

TerryA
TerryA

Reputation: 59974

You can do:

>>> def sieve(L, i):
...     temp = L[:i]
...     for x, y in zip(L[i::2], L[i+1::2]):
...             temp.append(x)
...             temp.append(y/2)
...     return temp
... 
>>> sieve([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)
[1, 2, 3, 2, 5, 3, 7, 4, 9, 5]

Note that itself * (2 - 1 ) / 2 is equivalent to itself * 1 / 2 which is equivalent to itself / 2.

Upvotes: 2

user2357112
user2357112

Reputation: 280227

NumPy would actually let you do that!

>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> i = 2
>>> a[i*2::2] *= (i-1.0)/i
>>> a
array([0, 1, 2, 3, 2, 5, 3, 7, 4, 9])

If you can't use NumPy or prefer not to, a loop would probably be clearest:

>>> a = range(10)
>>> for j in range(i*2, len(a), i):
        # Not *= since we want ints
...     a[j] = a[j] * (i - 1) / i

Upvotes: 3

llb
llb

Reputation: 1741

Per your edit, you can do this with a range.

for i in range(1, len(listnums), 2):
    listnums[i] /= 2

If you want to do this with a list comprehension, you can do it similarly to the other version using enumerate.

def sieve(listnums, divisor):
    return [num if i % divisor else num/divisor for i, num in enumerate(listnums, 1)]

Upvotes: 1

qaphla
qaphla

Reputation: 4733

map(lambda x : x * (2 - 1) / 2 if x % 2 == 0 else x, list)

This should do what you want it to.

Edit:

Alternately in style, you could use list comprehensions for this as follows:

i = 2
list[:i] + [x * (i - 1) / i if x % i == 0 else x for x in list[i:]]

Upvotes: 1

Related Questions