How to change the last list element to -1? - python

Write a function that accepts a list. The function should change the element of a list with a max value on its right side. The last element of a list should be changed to -1.
Input: [17, 18, 5, 4, 6, 1]
Output: [18, 6, 6, 6, 1,−1]
I was able to do the first part but I can't seem to change the value of the last element to -1.
def list_change(lista):
for i in range(0, len(lista)):
if i == (len(lista) - 1):
x = 0 - 1
lista[i] = lista[x]
else:
tmax = -100000000
for j in range(i + 1, len(lista)):
if lista[j] > tmax:
lista[i] = lista[j]
tmax = lista[j]
print(lista)
list_change([17, 18, 5, 4, 6, 1])

It is easy, change the last element using its index -
def list_change(lista):
for i in range(0, len(lista)):
if i == (len(lista) - 1):
x = 0 - 1
lista[i] = lista[x]
else:
tmax = -100000000
for j in range(i + 1, len(lista)):
if lista[j] > tmax:
lista[i] = lista[j]
tmax = lista[j]
lista[-1] = -1 # Get the last element and change it.
print(lista)
list_change([17, 18, 5, 4, 6, 1])

To get the last element of the list, use the list[-1] syntax. The list[-n] syntax gets the nth-to-last element. So list[-1] gets the last element, list[-2] gets the second to last.
list[-1] = -1
Edit: first of all, don't use list as a variable, list is used to create a new list as list(...) as an alternative to [...]. Secondly, check the list is not empty before making the aforementioned call.
So if variable x is referencing a list object
if not x:
x.append(elem)
else:
x[-1] = elem

Related

How to compare each element in the list and check if it's bigger then the element on the right

hello I am struggling with this problem for school and can't get my code to do what it needs to solve this. The question is: Define an element of a list of items to be a dominator if every element to its right (not just the one
element that is immediately to its right) is strictly smaller than that element. It wants me to count how many denominators are in the list.
def extract_increasing(digits):
countDem = 0
#check and see if there is anything in the list
if not digits:
return 0
#compare the first element to the one on the right of it
for x in range(len(digits)):
for y in range(x + 1, len(digits)):
if digits[x] > digits[y]:
countDem += 1
return countDem
The code below should check if a number in the list is a dominator.
def is_dominator(lst, idx):
for i in range(idx + 1, len(lst)):
if lst[i] >= lst[idx]:
return False
return True
digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in digits:
print(is_dominator(digits, i))
The error in your code is that you're adding one for the counter every time the next value meets the condition.
for x in range(len(digits)):
for y in range(x + 1, len(digits)):
if digits[x] > digits[y]:
countDem += 1
Every time digits[x] > digits[y] is met you add one to your counter. You should only add one once you checked that all values to the right meet the condition.
isDem = False
for x in range(len(digits)):
for y in range(x + 1, len(digits)):
if digits[x] > digits[y]:
isDem = True
else:
isDem = False
#Once you went through all the values to the right you can add one to the counter
if isDem ==True:
countDem += 1
Hope that helps!
You start in the last element, and save always the max_element in every iteration, then you know always if exist some number grater than the current number. This is a little more efficient because it runs through the array only once.
def dominator(li: list):
sol = 0
max_number = -math.inf
for i in range(len(li)-1, -1,-1):
if li[i] > max_number:
sol+=1
max_number = li[i]
return sol
Try list comprehension
lst = [0, 10, 2, 6, 7]
new_lst = [v for k,v in enumerate(lst) if all(v > x for x in lst[k+1:])]
# [10, 7]
Update
def extract_increasing(digits: list) -> int:
countDem = 0
for x, y in enumerate(digits):
if all(y > a for a in digits[x+1:]):
countDem += 1
return countDem
lst = [0, 10, 2, 6, 7]
extract_increasing(lst) # -> 2

Counting sort a list in descending order

So basically I want to figure out how to reverse a counting sort. This is the code I found:
def countingSort(myList):
maxValue = 0
for i in range(len(myList)):
if myList[i] > maxValue:
maxValue = myList[i]
buckets = [0] * (maxValue + 1)
for i in myList:
buckets[i] += 1
i = 0
for j in range(maxValue + 1):
for a in range(buckets[j]):
myList[i] = j
i += 1
return myList
if __name__ == '__main__':
sortedList = countingSort([1,23,4,5,6,7,8])
print(sortedList)
So I decided to change line 16 to this:
i -= 1
The results are very close, but I get this:
[1, 23, 8, 7, 6, 5, 4]
My issue is that 1 is before 23 for some reason. I tried reverting some of the other signs, but it usually results in an out of bounds error. Any ways to work around it?
Reverse the range that j iterates through so you start from high numbers then end with low numbers:
for j in range(maxValue, -1, -1):
With i -= 1 you're writing at indices 0, -1, -2, -3 etc. That is, you write the smallest number (the 1) at the front, and then the remaining numbers from the back backwards. You can make it work by starting with i = -1.

Find consecutive integers in a list

I am trying to find consecutive values from an unsorted list. Experimental code below:
num = [8, 9, 4, 1, 2, 3]
#(num[0+1]) next value
for i in range(len(num)-1): # not using -1 will cause index error
if num[i]+1==num[i+1]:
print('Con',num[i])
Problem: I am unable to get the last value with this current code. My output excludes the last value. Here is what I get (no 9 or no 3):
Con 8
Con 1
Con 2
I have seen a few complex solutions which were a little difficult for me to understand. Is it possible to tweak the for loop part a little and get the entire sequence? Thanks a lot.
You can use the function groupby:
from itertools import groupby
num = [8, 9, 4, 1, 2, 3]
# Enumerate and get differences between counter—integer pairs
# Group by differences (consecutive integers have equal differences)
gb = groupby(enumerate(num), key=lambda x: x[0] - x[1])
# Repack elements from each group into list
all_groups = ([i[1] for i in g] for _, g in gb)
# Filter out one element lists
list(filter(lambda x: len(x) > 1, all_groups))
# [[8, 9], [1, 2, 3]]
This is because you only check the next number. When you want the second number (like 9 or 3), you have to include a check for the previous number too. This will make the if a bit longer, but it'll work.
num=[8,9,4,1,2,3]
for i in range(len(num)):
if (
( # check for the next number
i + 1 != len (num) and # don't check the end of the list
num[i]+1==num[i+1]
) or ( # check for the previous number
i != 0 and # don't check before the list
num [i-1] == num [i] - 1
)
): print('Con',num[i])
Also, I had to remove the -1 in your range, because I already do a manual check, and as pointed out, this prvented 3 from being shown.
Your code only tests in one direction (being followed by a consecutive number).
For the full sequence you have to test in both direction.
num=[8,9,4,1,2,3]
assert(len(num) > 1)
for i, n in enumerate(num):
if i != 0:
if n == num[i-1] + 1:
print("Con", n)
continue
if i != len(num) - 1:
if n == num[i+1] - 1:
print("Con", n)
One way would be to print both numbers when you found them to be consecutive, but also check that the one at index i-1 was not in the consecutive list as well so that the number at index i is not printed twice:
num = [8, 9, 4, 1, 2, 3]
for i in range(len(num)-1): # not using -1 will cause index error
if num[i] + 1 == num[i + 1]:
if i == 0 or (i - 1 >= 0 and num[i - 1] != num[i] - 1):
print('Con', num[i])
print('Con', num[i + 1])
Could try with a more complex list as well:
num = [8, 9, 4, 1, 2, 3, 4, 4, 8, 9, 1, 2, 3, 0, 1, 5, 6, 1]
for i in range(len(num)-1): # not using -1 will cause index error
if num[i] + 1 == num[i + 1]:
if i == 0 or (i - 1 >= 0 and num[i - 1] != num[i] - 1):
print('Con', num[i])
print('Con', num[i + 1])
num = [8, 9, 4, 1, 2, 3]
def con(rng, pos=0):
if pos < len(rng):
if (pos > 0 and rng[pos]-1 == rng[pos-1]) or (pos < len(rng) -1 and rng[pos]+1 == rng[pos+1]):
print("con", rng[pos])
con(rng, pos+1)
con(num)
edit:
this is solution is based on concurrent function, and needs only the list as argument. As long as they are within lower-/upperbound of list, the function will check if (previous number)-1 or (next number)+1 are equal (this number)
output will be:
con 8
con 9
con 1
con 2
con 3

Comparing a sequence of numbers in a python list

I would like to make a loop to take a number, compare with the next number and if the condition is true, replace this number by the next number and compare this number to the next until this number not fits more in the condition.
I tried this code but the looping does not work.
list = [9,4,3,1,8,10,4,3,2]
for i,item in enumerate(list):
p = item
while p > list[i+1]:
p = list[i+1]
else:
print(p)
You can find the local minima (I want the output the number: 1 and 2. (the minimal point in a wave)) for your list:
>>> data = [9, 4, 3, 1, 8, 10, 4, 3, 2]
by adding infinity to both end so that the first and the last element will also be found as a minimum:
>>> padded = [float('inf')] + data + [float('inf')]
and comparing a value with the one to its left and its right:
>>> [v2 for v1, v2, v3 in zip(padded[:-2], padded[1:-1], padded[2:]) if v1 > v2 < v3]
[1, 2]
list = [9,4,3,1,8,10,4,3,2]
list.append(float('Inf'))
for i,item in enumerate(list[:-1]):
if i == 0:
# skip this one, but make i count from 0
continue
if list[i-1] > item < list[i+1]:
print(item)

builtins.IndexError: list index out of range

I have this function here:
def swap_cards(deck, index_deck):
swap_deck = []
after_index = []
bandf_index = []
if index_deck >= len(deck):
for i in range(0, len(deck) + 1):
if deck[i] == index_deck:
after_index += [deck[0]]
else:
bandf_index += [deck[i]]
swap_deck += [deck[index_deck]] + bandf_index[1:index_deck - 1] + after_index
Every time I try to input an index that is greater than or equal to the deck length I get the error 'list index out of range'
Example:
swap_cards([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 9)
I expect [9, 1, 2, 3, 4, 5, 6, 7, 8, 0] but am instead getting 'list index out of range'.
Switching the last and the first number, I don't know what I am doing wrong.
You have a problem with len(). Assuming your index_deck is 9 as in the example above:
if index_deck >= len(deck):
for i in range(0, len(deck) + 1):
This range will yield [0,1,2,3,4,5,6,7,8,9,10,11]
if deck[i] == index_deck:
after_index += [deck[0]]
Since array indexes are zero-based, the above line will generate the error. deck[10] and deck[11] don't exist.
else:
bandf_index += [deck[i]]
Fixing the above len() statement will fix this as well (again, you may try to access deck[10] if the if statement is false.
swap_deck += [deck[index_deck]] + bandf_index[1:index_deck - 1] + after_index
Final thing: you verify that if index_deck >= len(deck):. This will break the above line at deck[index_check] since here you will always access an index which does not exist.

Categories

Resources