Changing a list item without changing original values - python

I'm doing some practice problems and one program is asking me to change numbers in the list to 99, only if the number previously is even. I'm running into the trouble that when I change the number to 99, when it moves on the the next number, it checks to see if 99 is even, which I don't want, I want it to check the original value I had there, not what I changed it to .
d = [9, 8, 2, 15, 6, 33, 10, 4]
i = 1
while i < len(d) - 1 :
if d[i-1]%2 == 0 :
d[i] = 99
i = i + 1
print d
returns [9, 8, 99, 15, 6, 99, 10, 4]
I want it to return [9,8,99,99,6,99,10,99]
How would I add 99 into the original list without changing its original value if that makes any sense? List methods like pop or insert can not be used.

Try this.
d = [9, 8, 2, 15, 6, 33, 10, 4]
for i in reversed(xrange(1, len(d))):
d[i] = 99 if d[i - 1] % 2 == 0 else d[i]

I would advice to iterate descending:
d = [9, 8, 2, 15, 6, 33, 10, 4]
for x in xrange(len(d)-1, 0, -1):
if d[x - 1] % 2 == 0:
d[x] = 99
print d
In this case next iteration will operate not changed values.
Or You can create new list
or You can add variable for previous value and use it in if statement
d = [9, 8, 2, 15, 6, 33, 10, 4]
previous = d[0]
for i, x in enumerate(d[1:]):
if previous % 2 == 0 :
previous = d[i]
d[i] = 99
else:
previous = d[i]
print d

search the list backwards
see last and before last value (n-1, n-2)
change the last value if needed
move to previous values (n-2,n-3)
repeat until whole list is updated

Try this:
d = [9, 8, 2, 15, 6, 33, 10, 4]
prev=d[0]
for i,j in enumerate(d):
if prev%2==0:
prev=j
d[i]=99
else:
prev=j
print d

Related

python strings and insider condition

well I am learning on Udemy and I couldn't figure out why the result of this lines of code:
numbers = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
result = [num + 3 for num in numbers if num % 2 == 0]
print(result)
are [5, 11, 37] and not [4, 4, 6, 8, 16, 24, 58]?
thank you for helping.
if num % 2 == 0
means that you only want to execute the code if num is even.
That way only the 2,8 and 34 are added to the list and incremented by 3.
The answer you expect (only the odd numbers incremented by 3) is when the last bit is like this:
if num % 2 != 0
for num in numbers iterates over elements of the list.
if num % 2 == 0 restricts to even numbers.
So you end up by adding 3 to : 2, 8 and 34 which gives the expected result.
A more explicit loop would be :
numbers = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
result = []
for num in numbers:
if num%2 == 0: # if it's even
result.append(num+3)
print(result)

Inserting a value to list according to a threshold value

I have list a = [1,2,3,6,8,12,13,18,33,23] and list b=[] that is empty. I need each value in list a compare with all the values in the list b by taking the difference of the new value from list a with all the contents of the list b. If the difference is grater than to the value of the threshold, it must insert to list b rather than skip to the next value in a, how can do that?
a =[1,2,3,6,8,12,13,18,33,23]
b=[]
b.append(a[0])
for index in range(len(a)):
for i in range(len(b)):
x = a[index] - b[i]
if x > 1:
b.append(a[index])
print("\nOutput list is")
for v in range(len(b)):
print(b[v])
The desired output is:
output = [1,6,8,12,18,33,23]
To further clarify, in first time the list b have the first item from list a. I need to check if the a[0]-b[0]>1, then insert the value of a[0] in b list, and next if a[1] - b[0]>1 then insert the a[1] in b list , and if [[a[2] -b[0] >1] and [a[2]-b[1] > 1]] then insert a[2] in b list and so on
Here is the probable solution to the stated problem though the output is not matching with your desired outcome. But sharing on the basis of how I understood the problem.
a = [1, 2, 3, 6, 8, 12, 13, 18, 33, 23]
b = []
b.append(a[0])
threshold = 1 # Set Threshold value
for index in range(len(a)):
difference = 0
for i in range(len(b)):
difference = abs(a[index] - b[i])
if difference > threshold:
continue # Keep comparing other values in list b
else:
break # No need for further comparison
if difference > threshold:
b.append(a[index])
print("\nOutput list is")
print(b)
Output is:
Output list is
[1, 3, 6, 8, 12, 18, 33]
Also, I notice that after swapping the last two elements (33 <-> 23 ) of the list a as below:
a = [1, 2, 3, 6, 8, 12, 13, 18, 23, 33]
and running the same code. the output was near to your desired output:
Output list is
[1, 3, 6, 8, 12, 18, 23, 33]
This problem is very interesting now as I put myself into more investigation. And I found it a very interesting. Let me explain. First consider the list a as a list of integer numbers starting from 1 to N. For example:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
and set the threshold to 1
threshold = 1 # Set Threshold value
Now, run the programme with threshold = 1 and you will get the output:
Output list is
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
and if you rerun with threshold = 2, you will get the following output:
threshold = 2
Output list is
[1, 4, 7, 10, 13, 16, 19]
Basically, this programme is basically generating a hopping series of integer numbers where hopping is set to the threshold value.
Interesting!!! Isn't it???

When trying to print out elements in a list lesser than 10 within 1 line of code, why is the address outputted instead

I expected this print statement to print each element lesser than 5 one at a time but got the address returned instead.
Any idea what to do if I want to print each element lesser than 5 one at a time within 1 line of code
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print(num for num in a if num < 5)
[out]:
<generator object <genexpr> at 0x7efd6ce74cf0>
# This is the correct solution if I want to print it in a list
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print([i for i in a if i<5])
[out]:
[1,1,2,3]
I am new to python but as far as I know this is the best way to do what you are asking.
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print("\n".join([str(num) for num in a if num < 5]))
this is just the same code as the one you use above but I have also added the .join() method to separate out each element of the list and print it on a separate line. I used the "\n" to print everything on separate lines though if this is not what you wanted you could simply change that to an empty string: "" or a space: " ".
not sure if this is exactly what you are asking but I hoped it helped.
Doing the for loop inside [] brackets is a List Comprehension
You can instead re-factor your code to for loop through each item in the list then print if one is less than 5 doing the following:
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
for x in a: print(x) if x < 5 else 0
The output for the following code is:
1
1
2
3
The above code is the same as doing:
for x in a:
if x < 5:
print(x)
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
list(map(print, (num for num in a if num < 5)))

Python array logic

I am trying to create a list of lists with the input of m and n, where m is the number of lists within the main list and n is the number of elements within each given list. The grid should contain the integers from start to start + rows * cols - 1 and be ascending. But, every odd numbered row should be descending instead.
The code I've written is returning the expected results, but my automated tester is saying it's incorrect. Maybe my logic is messed up somewhere?
inputs:
start = 1, m = 3, n = 5
expected:
[[1,2,3,4,5],[10,9,8,7,6],[11,12,13,14,15]]
result = []
mylist = []
start = 1
for x in range(0, rows):
for x in range(0, cols):
result.append(start)
start += 1
for y in range(0, rows):
if y%2 != 0:
mylist.append(result[cols - 1::-1])
del result[cols - 1::-1]
else:
mylist.append(result[0:cols])
del result[0:cols]
return mylist
One possible solution, using itertools.count:
from itertools import count
def build(m, n, start=1):
lst, c = [], count(start)
for i in range(m):
lst.append([next(c) for j in range(n)][::-1] if i % 2 else [next(c) for j in range(n)])
return lst
print(build(3, 5, 1))
Prints:
[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15]]
print(build(3, 0, 1))
Prints:
[[], [], []]
just generate the list of numbers you need which will be n * m, in your case that would generate 0 to 14 in the python range function. However as we want to start at ` then we need to add the start offset too the range end.
Now we can generate all the numbers we need we just need to think about how to create them.
well we can add numbers to the list until the list reaches the size of n, then we need to start a new list, However if the list we just finished is an even numbered row then we need to reverse that list.
def build_lists(m, n, start=1):
data =[[]]
for i in range(start, n * m + start):
if len(data[-1]) < n:
data[-1].append(i)
else:
if len(data) % 2 == 0:
data[-1] = data[-1][::-1]
data.append([i])
if len(data) % 2 == 0:
data[-1] = data[-1][::-1]
return data
print(build_lists(3, 5))
print(build_lists(6, 3))
print(build_lists(6, 2, 100))
OUTPUT
[[1, 2, 3, 4, 5], [10, 9, 8, 7, 6], [11, 12, 13, 14, 15]]
[[1, 2, 3], [6, 5, 4], [7, 8, 9], [12, 11, 10], [13, 14, 15], [18, 17, 16]]
[[100, 101], [103, 102], [104, 105], [107, 106], [108, 109], [111, 110]]

Why is my index variable not iterating my list correctly?

I wrote a small piece of code to iterate over a list and sum the contents (I know there is a built in function but wanted to do this out of curiosity).
list = [14, 42, 100, 15, 8, 16, 104, 8, 41, 5, 15, 10]
index = 1
result = list[0]
for range in (0, len(list)):
result = result + list[index]
index = index + 1
print(result)
For some reason the index variable iterates until '3' and just stops. Thanks for the help.
Why?
Because for range in (0, len(list)) will iterate only two times:
With value 0.
With value len(list) which is 12.
So, you end up adding only first 3 elements in list.
# Wrong code
result = list[0]
for range in (0, len(list)):
result = result + list[index]
index = index + 1
# 14 + 42 + 100 = 156
Corrected:
lst = [14, 42, 100, 15, 8, 16, 104, 8, 41, 5, 15, 10]
result = 0
for i in range(len(lst)):
result = result + lst[i]
print(result)
More pythonically:
lst = [14, 42, 100, 15, 8, 16, 104, 8, 41, 5, 15, 10]
result = 0
for x in lst:
result += x
print(result)
Shorter:
sum(lst)
Note-
Don't name:
your list as list as it shadows the built-in list.
your variable as range as it shadows the built-in range.
this is really basic.
summ = 0
for i in range(len(list)):
summ += list[i]
your for-loop is simply incorrect. You iterate over the elements of the tuple with two elements, plus one sums up to three...
You are iterating over a tuple with two elements, 0 and len(list).
You should use range, to get a range over all numbers from 0 to len(list):
result = list[0]
for index in range(1, len(list)):
result = result + list[index]
but you should iterate over the elements of the list directly:
numbers = [14, 42, 100, 15, 8, 16, 104, 8, 41, 5, 15, 10]
result = 0
for number in numbers:
result += number
Alternate solution: when you want to get each element’s index and value at the same time, a more elegant solution uses enumerate(). This avoids us to worry about len and incrementing the index
Note: We are not using the index below though
lst = [14, 42, 100, 15, 8, 16, 104, 8, 41, 5, 15, 10]
result = 0
for i, num in enumerate(lst):
result += num
print(result)

Categories