Python3: Reverse a list using only while, .pop() and .insert() - python

I am trying to do the following exercise:
Challenge: reverse a list using while .pop() insert() pop() the first item in the list and add to the beginning of a new string that will be reversed
some_numbers =[1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77]
Here's the code I have written:
some_numbers =[1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77]
new=[]
while some_numbers:
x=some_numbers.pop() #Should delete the last item on the list
new.insert(-1,x) #Should insert it in -1 position on the list
print(new)
However, this is the result I am getting:
[66, 55, 44, 33, 22, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 77]
Does somebody know how can I make the "77" at the beginning on the list? I tried populating new=[" "] and it works but obviously the space appears as part of the list in the result and I just want the numbers there. Thanks!!

Try inserting at len(reverse):
some_numbers =[1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77]
reverse = []
while some_numbers:
reverse.insert(len(reverse), some_numbers.pop())
print(reverse)
Output
[77, 66, 55, 44, 33, 22, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1]
From the documentation:
Insert an item at a given position. The first argument is the index of
the element before which to insert, so a.insert(0, x) inserts at the
front of the list, and a.insert(len(a), x) is equivalent to
a.append(x).
Notice that:
The first argument is the index of the element before which to
insert
When you do insert(-1, x), your code inserts before the last element, for example if you print reverse at each stage, you get:
[77]
[66, 77]
[66, 55, 77]
[66, 55, 44, 77]
[66, 55, 44, 33, 77]
[66, 55, 44, 33, 22, 77]
...

You can solove this challenge using with a single variable(i):
some_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77]
new = []
i = 0
while some_numbers:
x = some_numbers.pop() # Should delete the last item on the list
new.insert(i, x) # Should insert it in -1 position on the list
i += 1
print(new)

Always pop the first item of some_numbers and insert it at the beginning of the new list, which is what the question stated was to be done:
>>> some_numbers = [1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77]
>>> new = []
>>> while some_numbers:
... new.insert(0, some_numbers.pop(0))
...
>>> new
[77, 66, 55, 44, 33, 22, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>>
Why the OP's Answer Does Not Work
new.insert(-1, 3) inserts 3 before the last element of new. When new is empty, 3 is just inserted and we have [3] as the result. But subsequent insertions are inserted before the last element, which is 3. Thus, the first element inserted will always be the last element of the final list. In the example below, that will be the number 3:
>>> l = []
>>> l.insert(-1, 3)
>>> l
[3]
>>> l.insert(-1, 2)
>>> l
[2, 3]
>>> l.insert(-1, 1)
>>> l
[2, 1, 3]
>>>
So instead of reversing 1, 2, 3 to get 3, 2, 1, we end up with 2, 1, 3. 3 should have been at the beginning of the final result but it is instead at the end because it was the first item inserted.

Reverse the following list using python without using a list-reversed function. what about this?
List_new=[22 , 33 ,44 ,55 ,66 ,77 ,88]

Related

How to find the index of the last odd number in a list, without reversing the list?

Have this so far, and essentially want to get there is something wrong with the position of last_odd as the compiler says the pop index is out of range?
def remove_last_odd(numbers):
has_odd = False
last_odd = 0
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
has_odd = True
last_odd = numbers[num]
if has_odd:
numbers.pop(last_odd)
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.
So basically, the solution to your problem would be to replace last_odd = numbers[num] with last_odd = num.
As #DeepSpace said, list.pop will
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.
So basically, the solution to your problem would be to replace last_odd = numbers[num] with last_odd = num.
list.pop() receive index as argument and remove the value. So, last_odd should be assigned to num instead of numbers[num]
Your function doesn't have return value yet. It should return numbers list.
def remove_last_odd(numbers):
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
last_odd = num
numbers.pop(last_odd)
return numbers
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
print(remove_last_odd(numbers))
# [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
Or iterating numbers value and using remove() method instead of pop():
def remove_last_odd(numbers):
for num in numbers:
if num % 2: last_odd = num
numbers.remove(last_odd)
return numbers
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
print(remove_last_odd(numbers))
# [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
No need to reverse the list but you can search it in reverse.
def remove_last_odd(numbers):
for i in range(len(numbers)-1, -1, -1):
if numbers[i] & 1:
numbers.pop(i)
break
numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
remove_last_odd(numbers)
print(numbers)
Output:
[1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 6]
Option:
If you insist on a 'forward' search then:
def remove_last_odd(numbers):
ri = -1
for i, v in enumerate(numbers):
if v & 1:
ri = i
if ri >= 0:
numbers.pop(ri)
To get the index of the last odd element you can use the reversed() iterator which will not reverse the original list object.
A quick way to get the index is:
>>> numbers = [1, 7, 2, 34, 8, 7, 2, 5, 14, 22, 93, 48, 76, 15, 6]
>>> -next(filter(lambda v: v[1]%2==1, enumerate(reversed(numbers))))[0]
-1
Even for very large lists with a lot of even numbers at the end the result will be delivered quite quick (compared with the proposed code):
>>> from timeit import timeit
>>> def find_last_odd(numbers):
for num in range(len(numbers)):
if numbers[num] % 2 == 1:
last_odd = num
return last_odd
>>> numbers2=numbers+([2]*10000) # create a list with 10000 even numbers at the end!
>>> timeit(lambda: find_last_odd(numbers2),number=100)
0.5675344999999936
>>> timeit.timeit(lambda: -next(filter(lambda v: v[1]%2==1, enumerate(reversed(numbers2)))).__getitem__(0),number=100)
0.10892959999998197

how to add up the elements of list s with even indexes in one line?

I am learning python and couldn't figure it out. I got to this point and am stumped.
def func5(s):
return [s for i in range(len(s)) if i % 2 == 0]
in: print(func5([1, 2, 3, 4]))
out: [[1, 2, 3, 4], [1, 2, 3, 4]]
It shouldn't show that way of course. Elements with even indexes must be added to all elements.
in ---> [1, 2, 3, 4]
out---> [5, 6, 7, 8]
It's really hard to decipher what your actual end-result should be, because you haven't really explained the logic fully in your question.
My answer will be based on my own understanding of your description, which follows:
For each integer in list s, add the sum of the indexes of all even
values of s. Do this all using a one-liner function.
Using your example of [1, 2, 3, 4], we can check what values should summed:
>>> [(idx, val) for idx, val in enumerate([1, 2, 3, 4]) if val%2 == 0]
[(1, 2), (3, 4)]
So for that list, we should add sum(1,3) to each integer.
Before we create a "one-liner" to solve the problem, let's create a more "verbose" solution of the problem:
def evenIndexes(int_list):
evenIntSum = sum([idx for idx, i in enumerate(int_list) if i % 2 == 0])
new_int_list = []
for integer in int_list:
new_int_list.append(evenIntSum + integer)
return new_int_list
Which you can immediately shorten to two list-comprehensions instead, to create a two liner:
def evenIndexes(int_list):
evenIntSum = sum([idx for idx, i in enumerate(int_list) if i % 2 == 0])
return [integer + evenIntSum for integer in int_list]
Now that is already quite compact but if you want to compact it even further, then you will have to nest the two list-comprehensions:
def evenIndexes(int_list):
return [i + sum([idx for idx, _ in enumerate(int_list) if _ % 2 == 0]) for i in int_list]
However, keep in mind that the above piece of code "summarizes" all of the even indexes once for each integer in the original list instead of just using the already calculated value like the other versions does. That means that the larger that list grows, the more inefficient the loop becomes.
Here are some random examples of the code running:
Original List: [1, 2, 3, 4]
Iterated List: [5, 6, 7, 8]
Original List: [61, 46, 86, 10, 68]
Iterated List: [71, 56, 96, 20, 78]
Original List: [33, 96, 34, 96, 95]
Iterated List: [39, 102, 40, 102, 101]
Original List: [92, 13, 44, 57, 71]
Iterated List: [94, 15, 46, 59, 73]
Original List: [18, 45, 20, 16, 66]
Iterated List: [27, 54, 29, 25, 75]

Subtract dynamic value from every value in list

Apologies if my explanation below is poor, but I am fairly new to python scripting.
I'm trying to find a way to product a list of number that subtracting a set_value from an item in a list, then take the new_value and subtract it from the next item in the list, and so on.
For example:
subtraction_list = []
set_value = 100
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
set_value - list[0] = 99
new_set_value = 99
new_set_value - list[1] = 98
...
subtraction_list = [99, 97, 94, 90, 85, 79, 72, 64, 55, 45]
Regardless, any help would be greatly appreciated!
You can do this in a functional way by leveraging itertools.accumulate to make an iterator the yields the cumulative sum of your list.
It works like this:
from itertools import accumulate
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
m = accumulate([0] + l) # in 3.8 we can use accumulate(l, initial = 0)
list(m)
# [0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
You can zip this with your value and use it as part of the subtraction allowing you to avoid explicitly managing the state of the variable:
from itertools import accumulate
set_value = 100
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
m = accumulate([0]+l)
subtraction_list = [set_value - diff - n for diff, n in zip(m, l)]
# [99, 97, 94, 90, 85, 79, 72, 64, 55, 45]
For something completely different – if you are using python 3.8, you can use the walrus := operator here:
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
set_value = 100
subtraction_list = [set_value := set_value - n for n in l]
[One note: don't use list as a variable name. list is a built-in type in python that you can overwrite, which leads to hard-to-find bugs.]
First, you shouldn't use the variable name list, because it's the name of a built-in function, so you can try this with a simple loop:
set_value = 100
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
final_list=[]
for i in lst:
final_list.append(set_value-i)
set_value=set_value-i
final_list
>>>[99, 97, 94, 90, 85, 79, 72, 64, 55, 45]
Simlply loop through the list
subtraction_list = []
set_value = 100
list_of = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(len(list_of)):
set_value = set_value - list_of[i]
subtraction_list.append(set_value)

Python programming about list [duplicate]

This question already has answers here:
Removing duplicates in lists
(56 answers)
Closed 6 years ago.
In this program I want to remove the duplicate values from the list. This is what i wrote:
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
def loop():
for a in range(len(list)-1):
for b in range(a+1,len(list)):
if list[a] == list[b]:
del list[a]
print(list)
loop()
But, it's giving me this error:
Can you help me?
If you have numpy then you can do (I renamed your list to l to avoid ambiguity):
import numpy as np
l = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
l_no_duplicates = list( np.unique(l) )
The common approach to get a unique collection of items is to use a set. Sets are unordered collections of distinct objects.
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
newList = list(set(list))
[1, 2, 3, 5, 8, 13, 34, 21, 55, 89]
Do something like the following:
create new_list
for item in list:
if item not in new_list:
add item to new_list
list = new_list
In Python:
list = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
print list
new_list = []
for item in list:
if item not in new_list:
new_list.append(item)
list = new_list
print list
Now run python filename.py and you will see the difference between two lists.

Python - Function that sums list's with error

def somalist (lista):
listasoma = [0,0,0,0,0,0,0,0,0,0,0]
for i in lista:
for g in i:
if i.index(g) != 0 and i.index(g) != 1 and i.index(g) != 2 and i.index(g) != 3:
listasoma[i.index(g)] += g
else:
listasoma[i.index(g)] = g
print(listasoma)
return(listasoma)
x = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
print(somalist(x))
is that the function, it works doing the sum of each sublist but it preserves the the index [0], [1], [2] and [3] and sum the anothers. In this example I will use the list x, in this list the function works correctly. The exit of the program is:
[1, 2, 3, 4, 32, 18, 21, 24, 27, 30, 22]
is what I've said it preserves the members [0],[1],[2],[3] and sum the other indices of each sublist.
But when we use some number more than once, it fails.
using:X = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,**6**,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
the 6 (index 4) in second sublist was writen twice (the another at the index 5 at the same sublist)
the exit was :[1, 2, 3, 4, **22**, 12, 21, 24, 27, 30, 33]
It's wrong!
The correct exit should be: [ 1, 2, 3, 4, 16, 18, 21, 24, 27, 30, 33]
Can someone tell me where my code is wrong?
I would recommend ditching the index() approach entirely.
def somalist (lista):
return lista[0][:4] + [sum(item) for item in list(zip(*lista))[4:]]
This works on lists with repeated elements.
v
>>> x = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
>>> X = [[1,2,3,4,5,6,7,8,9,10,11],[1,2,3,4,6,6,7,8,9,10,11],[1,2,3,4,5,6,7,8,9,10,11]]
>>> print(somalist(x))
[1, 2, 3, 4, 15, 18, 21, 24, 27, 30, 33]
>>> print(somalist(X))
[1, 2, 3, 4, 16, 18, 21, 24, 27, 30, 33]
^^

Categories

Resources