Multiply every other element in a list - python

I have a list, let's say: list = [6,2,6,2,6,2,6], and I want it to create a new list with every other element multiplied by 2 and every other element multiplied by 1 (stays the same).
The result should be: [12,2,12,2,12,2,12].
def multi():
res = 0
for i in lst[0::2]:
return i * 2
print(multi)
Maybe something like this, but I don't know how to move on from this. How is my solution wrong?

You can use slice assignment and list comprehension:
l = oldlist[:]
l[::2] = [x*2 for x in l[::2]]
Your solution is wrong because:
The function doesn't take any arguments
res is declared as a number and not a list
Your loop has no way of knowing the index
You return on the first loop iteration
Not related to the function, but you didn't actually call multi
Here's your code, corrected:
def multi(lst):
res = list(lst) # Copy the list
# Iterate through the indexes instead of the elements
for i in range(len(res)):
if i % 2 == 0:
res[i] = res[i]*2
return res
print(multi([12,2,12,2,12,2,12]))

You can reconstruct the list with list comprehenstion and enumerate function, like this
>>> [item * 2 if index % 2 == 0 else item for index, item in enumerate(lst)]
[12, 2, 12, 2, 12, 2, 12]
enumerate function gives the current index of them item in the iterable and the current item, in each iteration. We then use the condition
item * 2 if index % 2 == 0 else item
to decide the actual value to be used. Here, if index % 2 == 0 then item * 2 will be used otherwise item will be used as it is.

Related

how to loop through each element in list and increment by one

Hello i want to ask how to loop through each element and increment every time by one this is what i want first i want to sum 0 , 1, 3 ,6 , 10 and after that sum can somebody help me about that i don't know how to tell if it is loop through each element or iterate.It should look like these examples.I am sorry!
ls = [0, 1, 3, 6, 10]
ls = [1, 3, 6, 10]
ls = [3, 6, 10]
ls = [6, 10]
ls = [10]
ls = []
Here's the problem who i want to solve it :
https://www.codewars.com/kata/5ce399e0047a45001c853c2b/train/python
I tried this but it doesn't work
def parts_sums(ls):
length_list = len(ls)
for i in range(0,length_list+1):
return length_list
Note that there is a built-in function sum() in Python that does that job probably better than any code you can write in Python.
sum([0, 1, 3, 6, 10])
However, if you want to practice writing your sum function by iterating through a list and summing all the elements, this is how you do it.
def my_sum(ls):
result = 0
for i in range(len(ls)):
result += ls[i]
return result
First of all, you need to initialize a variable to hold your result. The range() function generates all values from 0 to x. The for-loop assigns all values generated by the range function to i in order and executes the indented block below. The += assignment increments the left-hand side variable by the right-hand side expression value. At last, we return the result.
And if you prefer using a while-loop,
def my_sum(ls):
result = 0
i = 0
while i < len(ls):
result += ls[i]
i += 1
return result
It's always good to consult Python documentation when you are not sure how to use its built-in function.
If you want the accumulated sum of all items reversed, you can take a look at the accumulate function in itertools.
from itertools import accumulate
def parts_sums(ls):
return list(accumulate(ls[::-1]))[::-1] + [0]
Or if you want to implement with a loop,
def parts_sums(ls):
result = []
part_sum = 0
for item in ls[::-1]:
result.append(part_sum)
part_sum += item
result.append(part_sum)
return result[::-1]
Or if you want to do it without reversing the list (say if you want to yield the results)
def parts_sums(ls):
result = []
part_sum = sum(ls)
for item in ls:
result.append(part_sum)
part_sum -= item
result.append(part_sum)
return result
Note the algorithm is still O(n), not that time complexity matters in this case.
For the question you have mentioned in codewars, you need to loop it thro 2 loops and keep reducing the first element in the inner loop for sum.
def parts_sums(ls):
# your code
sum = []
for i in range(len(ls)):
sum_temp =0
for j in range(i,len(ls)):
sum_temp += ls[j]
sum.append(sum_temp)
sum.append(0) # for the final empty list
return sum
print(parts_sums([0, 1, 3, 6, 10]))
This test will check the execution time too. So you need to be fast.
Naive approach
You can use sum or create your own sum.
def parts_sums(ls):
return [
sum(ls[i:])
for i in range(len(ls) + 1)
]
But i means you'll need to loop in a list twice. So it will be slow.
Sneaky approach
In a list like [a, b, c, d, e] you are calculating:
[a+b+c+d+e, a+b+c+d, a+b+c, a+b, a, 0]. So let's start from last to first element. [0, a, a+b, a+b+c, a+b+c+d, a+b+c+d+e]. Now we see a cumulative iteration:
So get loop in the list, get the element, sum it with last element of the result ([0]) list and add it as the last element to the result list. Lastly reverse the result.
def parts_sums(ls):
res = [0]
for i in range(len(ls)-1, -1, -1):
res.append(res[-1] + ls[i])
return res[::-1]

How do you replace a list of 5 0's with the first 5 even numbers? (python)

even_numbers = [0] * 5
for i in range(1,11):
if i%2 ==0:
even_numbers[i]=i
I am getting the error 'list assignment index out of range', although i'm not quite sure what that means.
"List index out of range" basically means that you are trying to access an array index that doesn't exist.
In your code, your loop goes up to 10, and you are trying to assign a number to even_numbers[10], while your array only has 5 elements. Basically you're telling your program "give me the 10th element of this 5-element list", which does not make much sense. Your indices in this case only go from 0 to 4.
To fix your issue, try storing the current index in a variable:
even_numbers = [0] * 5
current_index = 0
for i in range(1,11):
if i%2 ==0:
even_numbers[current_index]=i
current_index += 1
Edit: Alternatively, why not loop through even elements only, using the step argument of the range() function?
even_numbers = [0] * 5
current_index = 0
#will increment 'i' 2 by 2, i.e. i will be 2, then 4, then 6, ...
for i in range(2,11, 2):
even_numbers[i/2]=i
current_index += 1
The message means that you are trying to access an element of the list which does not exist.
The list only has five elements with indices 0 to 4. Trying to assign a value to even_numbers[i], you will try to assign a value to all elements of the list in the range of 1 to 10. That's why you should change the indexing to even_numbers[i/2]
The simplest solution is to generate the list of even numbers in the first place.
even_numbers = list(range(1,11,2))
If, for some reason, you already have the list, it's doesn't really matter what the original contents are if you are just going to replace them.
for i, _ in enumerate(even_numbers):
even_numbers[i] = 2*i
or just even_numbers[:] = range(1, 11, 2)

how to only sum a part of elements in a list

I need this function to return the sum of the elements located at the odd indices.
And that's what I have right now:
def getSumOdds(aList):
for element in aList:
if element % 2 == 1:
Since you are doing for element in aList, element % 2 == 1 will check if each element is odd, not if its index is odd.
What you can do is this:
value = 0
for index in range(len(aList)):
if index % 2 == 1:
value += aList[value]
This goes through all of the indices, and if it's odd, adds the element at that index to the accumulator.
That method is fairly easy to understand; however, it goes through an unnecessary number of elements:
value = 0
for index in range(1, len(aList), 2):
value += aList[index]
range(x, y, z) generates all elements counting up from x up to but not including y, counting by z. This starts at 1 and takes every 2 elements.
This is rather long though, and can be shortened to the following:
value = sum(aList[index] for index in range(1, len(aList), 2))
Using list slicing, where aList[start:end:jump] gives every jump-th element starting from start up to end (implicity the very end), you can do the following:
value = sum(aList[1::2])
This sums every second element starting from the first.
If your input is not necessarily indexable (that is, it's iterable but cannot use [index] syntax, such as a set, range, map, etc), you can do:
value = sum(val for index, val in enumerate(anIter) if index % 2 == 1)
This sums every value where the index is odd by getting the index and value for each enumerated value. The enumerate function is an iterable which returns (0, a[0]), (1, a[1]), ..., (len(a) - 1, a[-1]).
Using the code you've already started, enumerate is probably the function you want which returns the count and the values in the list. Then we filter the odd indices and add them to a variable for the sum, as you had already done:
def getSumOdds(aList):
total = 0
for index, element in enumerate(aList):
if index % 2 == 1:
total += element
return total
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print getSumOdds(l) # 20 (odd indices: 2+4+6+8=20)
Just you can use a list slice list[1::2]
or function
def getSumOdds(aList):
return sum(aList[1::2])

Multiply odd indices by 2?

So I'm writing a function that is going to multiply each number at an odd index in a list by 2. I'm stuck though, as I really don't know how to approach it.
This is my code.
def produkt(pnr):
for i in pnr:
if i % 2 != 0:
i = i * 2
return pnr
If I, for example, type produkt([1,2,3]) I get [1,2,3] back but I would want it to be [2,2,6].
note that modifying i in your example does not change the value from the input list (integers are immutable). And you're also mixing up the values with their position.
Also, since indices start at 0 in python, you got it the wrong way.
In those cases, a simple list comprehension with a ternary expression will do, using enumerate to be able to get hold of the indices (making it start at 1 to match your case, you can adjust at will):
[p*2 if i%2 else p for i,p in enumerate(pnr,1)]
(note if i%2 is shorter that if i%2 != 0)
using list comprehensions:
multiply odd numbers by 2:
[x*2 if x%2 else x for x in pnr]
After clarification of question wording:
multiply numbers at odd indices by 2:
[x*2 if i%2 else x for i,x in enumerate(pnr)]
Consider using list comprehensions:
def produkt(pnr):
return [k * 2 if k % 2 else k for k in pnr]
Doing i = i * 2 you just override a local variable.
UPDATE (question was changed):
def produkt(pnr):
return [k * 2 if i % 2 else k for i, k in enumerate(pnr, 1)]
You can get the indices using enumerate, however that starts by default with index 0 (not 1) but it accepts a start argument to override that default.
The problem with your approach is that you don't change the actual list contents, you just assign a different value to the name i (which represented a list element until you assigned a different value to it with i = i*2). If you want it to work in-place you would need to modify the list itself: e.g. pnr[idx] *= 2 or pnr[idx] = pnr[idx] * 2.
However, it's generally easier to just create a new list instead of modifying an existing one.
For example:
def produkt(pnr):
newpnr = [] # create a new list
for idx, value in enumerate(pnr, 1):
# If you're testing for not-zero you can omit the "!=0" because every
# non-zero number is "truthy".
if idx % 2:
newpnr.append(value * 2) # append to the new list
else:
newpnr.append(value) # append to the new list
return newpnr # return the new list
>>> produkt([1,2,3])
[2, 2, 6]
Or even better: use a generator function instead of using all these appends:
def produkt(pnr):
for idx, value in enumerate(pnr, 1):
if idx % 2:
yield value * 2
else:
yield value
>>> list(produkt([1,2,3])) # generators should be consumed, for example by "list"
[2, 2, 6]
Of course you could also just use a list comprehension:
def produkt(pnr):
return [value * 2 if idx % 2 else value for idx, value in enumerate(pnr, 1)]
>>> produkt([1,2,3])
[2, 2, 6]
Try this:
def produkt(pnr):
return [ 2*x if i % 2 == 0 else x for i, x in enumerate(pnr)]
It will double every element in your list with an odd index.
>>> produkt([1,2,3])
[2, 2, 6]
Your code does not work, as i is no reference to the value inside the list, but just its value.
You have to store the new value in the list again.
def produkt(pnr):
for i in range(len(pnr)):
if pnr[i] % != 0:
pnr[i] *= 2
return pnr
or use this more convenient solution:
def produkt(pnr):
return [x * 2 if x % 2==0 else x for x in pnr]
Edit: As the question has been changed (completely) you should use this code:
def produkt(pnr):
return [x * 2 if ind % 2 else x for ind, x in enumerate(pnr)]
The first examples multiply each odd index by 2 and the former code multiplies the numbers at odd indices by 2.
Your problem is that i is a copy of the values in the pnr list, not the value in the list itself. So, you are not changing the list when doing i = i * 2.
The existing answers are already good and show the idiomatic way to achieve your goal. However, here is the minimum change to make it work as expected for learning purpose.
produkt(pnr):
new_pnr = list(pnr)
for ix in len(new_pnr):
if new_pnr[ix] % 2 != 0:
new_pnr[ix] *= 2
return new_pnr
Without new_pnr you'd be changing the list in place and then you wouldn't need to return it.

Python: Iterate through a list by value, not by index

How can I iterate through by something other than the index?
I have
L = [[1,2,3],[5,3,6],[5,4,14],[23,5,2],....,[11,13,6]]
notice how the middle element is increasing always by 1. the outer elements are pretty much random.
I want to be able to say something like this:
for i in L[2:4]:
which would iterate through the elements: [1,2,3],[5,3,6],[5,4,14], as opposed to looking at 2:4 as indexes.
so obviously the syntax of my for loop is incorrect. How can I do this?
[item for item in L if 2 <= item[1] <= 4]
is one way of doing it
def slice_special(a_list,slice_idx,minimum_value,maximum_value):
return [item for item in a_list if minimum_value <= item[slice_idx] <= maximum_value]
print slice_special(L,1,2,4)
or something more sophisticated like a dedicated data structure
class MyDataStructure:
def __init__(self,a_list):
self.my_data = a_list
def __getitem__(self,arg):
if isinstance(arg,slice):
return [item for item in self.my_data if arg.start <= item[arg.step] <= arg.stop]
raise Exception("%s is unscriptable"%self)
print MyDataStructure([[1,2,3],[5,3,6],[5,4,14],[23,5,2]])[2:4:1]
If you know the size of the elements of the list, you can unpack the sublists into the iteration variables:
>>> L = [[1,2,3],[5,3,6],[5,4,14],[23,5,2]]
>>> for a, b, c in L:
... print(a,b,c)
...
1 2 3
5 3 6
5 4 14
23 5 2
>>>
If you don't want to use a certain index, you can assign it to _, which is the standard way of notating unused variables.

Categories