Get previous value based in specific item - python

I am trying a script where we use a list item and then I will get the previous item.
lst = [1, 3, 4, 6, 8, 10]
next_item = next((x for x in lst if x > 6), None)
print next_item #8
This code works correctly for the item after 6. However i need the item before 6.
I am looking in docs for a prev method but i can't find anything related.
Any idea about that?

Assuming by "before" you mean "previous in lst", it is not necessary to use such a complicated way. This
lst[lst.index(6) - 1]
will give
4
while this
lst[lst.index(6) + 1]
will give
8
Of course you should check for index out of bound errors.

You can loop over the reversed list with a reverse condition :
>>> next((i for i in lst[::-1] if i<6),None)
4

If you are looking for the first number larger than 6 in lst, this is one way to do it:
lst = [1, 3, 4, 6, 8, 10]
lst2 =[]
for num in lst:
if num > 6:
lst2.append(num)
lst2.sort()
print lst2[0]
The output is 8

Related

Invert the list by exchanging the first and last element, the second and second last, and so on

So Basically the task is to invert the List by changing the first element with the last one, the second one with the second last etc...
This is what i tried, but nothing happend in the end. Do you have any ideas whats not working here or what different approach i should try?
list=[3,6,9,12,15,18,21,24,27,30]
y = 0
x = len(list)-1
while y <= x:
for i in list:
list[y],list[x]=list[x],list[y]
y+=1
x-=1
for i in list:
print(i)
All the other solutions are good approaches, but if you were specifically
asked to write the logic for inverting the list by changing the first element with last element and so on..here,
y = 0
x = len(list)-1
while y < x:
list[y],list[x]=list[x],list[y]
y+=1
x-=1
for i in list:
print(i)
You can do something like this:
def reverse(lst):
# Iterate over the half of the indexes
for i in range(len(lst) // 2):
# Swap the i-th value with the i-th to last value
lst[i], lst[len(lst)-1-i] = lst[len(lst)-1-i], lst[i]
lst = [1, 2, 3, 4, 5]
reverse(lst)
print(lst) # Outputs [5, 4, 3, 2, 1]
lst = [1, 2, 3, 4]
reverse(lst)
print(lst) # Outputs [4, 3, 2, 1]
You can use the reverse() function:
l = [3,6,9,12,15,18,21,24,27,30]
l.reverse()
You can do as follow:
l=[3,6,9,12,15,18,21,24,27,30]
new_l=l[::-1]
The following will invert the order of a list:
>>> l = [3,6,9,12,15,18,21,24,27,30]
>>> l[::-1]
Out[11]: [30, 27, 24, 21, 18, 15, 12, 9, 6, 3]
You can use this code :
for i in sorted(list,reverse=True):
print(i)

List index out of range using While loop

This is my first time posting and I am a bit of newbie so please excuse any errors in my question. I have to create a function that uses the While loop and takes in a list of numbers and adds each number to a new list until the a specific number is reached. For example - I want each number in a list to be added until the number 5 is reached in the list. If the number 5 is not in the list, then I would get the entire list as is. The issue I am having is with this last part. My current code, posted below, can give me a new list of numbers that stops at the number 5 but I get the "List index out of range" error when the number 5 is not included in the list. I am sure its something small that I am not factoring in. Any help or guidance on what I am doing wrong would be greatly appreciated.
def sublist(x):
i = 0
num_list = []
while x[i] != 5:
num_list.append(x[i])
i = i + 1
return num_list
print(sublist([1, 2, 5, 7])) #works fine
print(sublist([1, 2, 7, 9])) #list index out of range error
As others have pointed out, it is best to use a for loop when you already know the number loops you need (e.g.: len(x) in your case).
If you still really want to use a while loop instead, you will need to check every loop to see if you have checked every item in the old list, and exit the loop if you do. Here's what your code could look like if you're using a while loop:
def sublist(x):
i = 0
num_list = []
original_length = len(x)
while i < original_length and x[i] != 5:
num_list.append(x[i])
i = i + 1
return num_list
print(sublist([1, 2, 5, 7])) #works fine
print(sublist([1, 2, 7, 9])) #now also works fine
EDIT: I originally had the check for i < original_length inside the loop, I've changed it to be inside the while condition. BUT BE CAREFUL because the check MUST come before x[i] != 5. What I mean is that using this will work:
while i < original_length and x[i] != 5:
But this will not:
while x[i] != 5 and i < original_length:
This should do the trick. If n (5 in your example) is in the list x it will take the list until that point. Else, it will take the whole list. This isn't the most pythonic option, though, probably someone knows a better way.
def sublist(x, n):
num_list=[]
if n in x:
for i in x:
while i!=n:
num_list.append(i)
else:
num_list=x
return num_list
Your loop will not stop if there is no 5 in the list, so the index i will be equal to the length of x (length of x is out of range) in the iteration when the error happens.
When looping with python, it's better to use for in loops:
def sublist(x):
num_list = []
for n in x:
if n != 5:
num_list.append(n)
else:
break
return num_list
print(sublist([1, 2, 5, 7])) # [1, 2]
print(sublist([1, 2, 7, 9])) # [1, 2, 7, 9]
Try this
def sublist(x):
x.sort()
limit_num = 5
if limit_num not in x:return x
return x[:x.index(limit_num)]
print(sublist([1, 2, 5, 7]))
print(sublist([1, 2, 7, 9]))
Result:[1, 2]
[1, 2, 7, 9]

Appending a list through if condition in python

This could be a very basic question, but I realized I am not understanding something.
When appending new things in for loop, how can I raise conditions and still append the item?
For instance:
alist = [0,1,2,3,4,5]
new = []
for n in alist:
if n == 5:
continue
else:
new.append(n+1)
print(new)
Gets me
[1, 2, 3, 4, 5]
How do I get
[1, 2, 3, 4, 5, 5] # 4 is incremented, 5 is added 'as is'
Essentially, I want to tell python to not go through n+1 when n==5.
Would this be the only solution? append n==5 separately in a list and then sum new and the separate list?
Why don't you just append the 5 instead of using continue, is there any other condition?
for n in alist:
if n == 5:
new.append(n)
else:
new.append(n+1)
You can use the fact the a boolean True is 1 while a False is 0 combined with a list comprehension like:
Code:
[x + int(i != 5) for i, x in enumerate(alist)]
Test Code:
alist = [0, 1, 2, 3, 4, 5]
new = [x + int(i != 5) for i, x in enumerate(alist)]
print(new)
Result:
[1, 2, 3, 4, 5, 5]
Seems like you didn't get the point of 'continue'. The Python keyword 'continue', means you do nothing in that if condition, so basically you tell the program "do nothing" when n == 5 and if n is not 5, you do some operation. That's why you got your original result. Hope it may help.

How to modify a list in place

I want to add 1 to each element in the list without creating new one
i = [1,2,3,4,5]
for each in i:
i[i.index(each)] = each+1
print(i)
but it return like this...
[6,2,3,4,5]
seems that one add one in first element..but I want to add one for each..
lst = [1,2,3,4,5]
for i, x in enumerate(lst):
lst[i] = x + 1
print(lst)
Output
[2, 3, 4, 5, 6]
After incrementing 1 the next time i.index(each) always returns the first element in this case
for idx in range(len(i)):i[idx]+=1
Try using range of len of list
Ex:
i = [1,2,3,4,5]
for each in range(len(i)):
i[each]= i[each]+1
print(i)
Output:
[2, 3, 4, 5, 6]

Writing an implementation of Selection Sort in Python and my code is throwing "min() arg is an empty set" on a populated list

As an exercise, I am writing an implementation of selection sort (as well as insertion sort and quick sort); for me, the best way to gain a deeper understanding of a function is implementing it myself. I have the following code:
def selectionSort(L):
S = []
i = 0
a = len(L)
while i <= a:
S.append(min(L)) #Find min(L) and add it to set S
L.remove(min(L)) #Remove that same element min(L) from L
i += 1
return S #Return the sorted list
L = [int(x) for x in input('Input a list to be sorted: ').split()]
print(selectionSort(L))
The idea here is to have the user input a list of integers to be sorted and run the selectionSort() function on the list. For the life of me, I cannot figure out why min(L) is throwing the error min() arg is an empty sequence. I have written other code which takes a list as input in the same manner and it works fine.
You are looping once too many:
i = 0
a = len(L)
while i <= a:
#
i += 1
Here i goes from 0 through to len(a) inclusive, so you loop len(a) + 1 times. But there are only len(a) items in the list.
Your options are to pick one of the following
start i at 1, not at 0
stop at i < a (dropping the =) to not include len(a)
Use a for i in range(len(a)) loop; this produces values from 0 through to len(a) - 1.
Simply test if L is empty with
while L:
and remove a and i from your code altogether.
The latter option leads to less code and is clearer:
def selectionSort(L):
S = []
while L:
pick = min(L)
S.append(pick)
L.remove(pick)
return S #Return the sorted list
Note that I store the result of min(L) first to avoid scanning the list twice.
Your issue should already be fixed by #AChampion's comment, I just want to add some clarifications about what you're trying to do. The following code should work for you, but it still has some other issues:
def selectionSort(L):
S = []
i = 0
a = len(L)
while i < a: # Or even better: for i in range(len(L)) and without i += 1
S.append(min(L)) #Find min(L) and add it to set S
L.remove(min(L)) #Remove that same element min(L) from L
i += 1
return S
But, look at the following outputs:
>>> my_list = [3, 5, 1, 9, 2, 7, 4, 7, 4]
>>> selectionSort(my_list)
[1, 2, 3, 4, 4, 5, 7, 7, 9]
>>>
>>> my_list
[]
You see, the input my_list is empty now, because it is altered inside your function. To fix this issue, you can do: (because you may still need to use your original list)
def my_sort(my_list):
temp = my_list[:]
sorted_list = []
for i in range(len(temp)):
sorted_list.append(min(temp))
temp.remove(min(temp))
return sorted_list
Now, inside our function, we use a copy of our original list temp = my_list[:], this is equivalent to temp = copy.copy(my_list):
>>> import copy
>>>
>>> my_list = [3, 5, 1, 9, 2, 7, 4, 7, 4]
>>> id(my_list)
36716416
>>> l1 = my_list
>>> id(l1)
36716416 # In this case the id of l1 is the same as my_list's id!
>>> l2 = my_list[:]
>>> id(l2)
36738832 # This is NOT the same as my_list's id
>>> l3 = copy.copy(my_list)
>>> id(l3)
36766424 # This is NOT the same as my_list's id
Output of the new function:
>>> my_list = [3, 5, 1, 9, 2, 7, 4, 7, 4]
>>> my_sort(my_list)
[1, 2, 3, 4, 4, 5, 7, 7, 9]
>>>
>>> my_list
[3, 5, 1, 9, 2, 7, 4, 7, 4] # Our original list is still alive!
You may need:
As per your goal (implementing your own function for learning purpose), you may also need to use your own min function instead of the built-in one, the following is an example that you can try:
def my_min(my_list):
min = my_list[0]
for i in range(1, len(my_list)):
if min > my_list[i]:
min = my_list[i]
return min
Output:
>>> l1 = [3, 7, 2, 5]
>>> my_min(l1)
2

Categories