Trying to print the second largest number in list - python

x = input()
y = map(int, input().split())
score = list(y)
score2 = score.remove(max(score))
print(max(score2))
When I execute the above code with inputs x = 4 and y = 1 2 3 4, it shows an error message 'NoneType value is not iterable'. The last but previous line 'score2 = score.remove(max(score))' returns a None value. Why does this happen? I intend to create code which fetches the second largest number in the list

Method remove() from list doesn't return anything. It changes list inplace. So your score2 value will be always None.
The corrected program should look like (with few cosmetic corrections, will work for input of 2 values and higher):
score = sorted(map(int, input().split()))[-2]
print(score)

Why don't you just do -
y=[1, 2, 3, 4]
max_num = max(y)
print(max(num for num in y if num!=max_num))

Related

Strange behavior observed when iterating over list in python

I has a small question,
Let me share a small snippet of code
num = [1, 2, 3, 4]
for i in num:
print(i)
num[2] = 5
here the output is
1
2
5
4
the iterator's value got updated to 5 instead of 3 in the 3rd iteration, now if I do this
num = [1, 2, 3, 4]
for i in num:
print(i)
num = [5 if j == 3 else j for j in num]
the output is
1
2
3
4
the iterator stayed the same this the 3rd iteration
Does anyone know the reason for this behavior?
(I observed this in Python 3.8 or 2.7)
When you run the for loop, it takes the id of the provided object and iterates over it.
In the first code snippet, you are changing an element of the original object, so when the iterator reaches the second element it takes the updated value.
However, in the second case you are creating a new object with different values, but the object that you provided to the loop stays the same.
A way of checking this behaviour is to get the id of the variable before and after the modifications, and see how it does not change in the first case but it changes in the second case:
my_list = [1, 2, 3]
original_id = id(my_list)
# Check if the object identification changes after modifying one element
my_list[2] = 4
new_id = id(my_list)
if original_id == new_id:
print("1st case: The ID stays the same")
else:
print("1st case: The ID has changed")
# Check now what happens if you create a new list
my_list = [3, 2, 1]
new_id = id(my_list)
if original_id == new_id:
print("2nd case: The ID stays the same")
else:
print("2nd case: The ID has changed")
The obtained result is the following:
1st case: The ID stays the same
2nd case: The ID has changed
In your first code, your num[2]=5 replaces values in first loop instance itself, so 5 is printed in the normal loop.
Your second code:
It's actually replacing and only i is printed in second code.
You need to print num to check the replaced value.
Code:
num = [1, 2, 3, 4]
for i in num:
print(i)
num = [5 if j==3 else j for j in num ]
print (num)# This line
Output:
1
2
3
4
[1, 2, 5, 4]
The for loop already gets an iterator of num, and while inside loop you modify num, then the for loop does not look again to num, and iterates using the old list.

The highest even number in a list

I want to find the highest even number in a list. The code I have used is able to do so successfully, but I don't know why my code is running right.
Please find my code below:
def highest_even(*list):
for numbers in list:
if numbers % 2 == 0:
c= numbers
print(c)
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Even though I have only validated the even numbers, the output I am having is only the highest even number. Why is it so? Please help
Your list is ordered and you replace the value of c by the last value you evaluated as even. So at the end you get the highest number, try to shuffle your list using shuffle() and you will not get the right result.
Here's how you can fix your function :
def highest_even(*list):
c = 0
for numbers in list:
if numbers % 2 == 0:
if numbers > c:
c= numbers
print(c)
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
You can also create a list of evens, sort it, and take first value from the right:
def maxeven(list):
return sorted([x for x in list if x % 2 == 0])[-1]
I would do this instead: -
def highest_even(list):
evens = []
for i in list:
if i % 2 == 0:
evens.append(i)
return max(evens)
print(highest_even([1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555]))
Try to include print(c) inside the for() loop like so:
for numbers in list:
if numbers % 2 == 0:
c = numbers
print(c)
You get only the highest even number, because after the loop is done, you print only the last element.
You can obtain the Highest Even value From your mentioned tuple not list by using filter() and lambda Expression.
Highest Even Element in The Tuple
Code Syntax
def highest_even(*tuple):
lis = filter(lambda x: x % 2 == 0, tuple)
return print(f"your maximum even number is: {max(lis)}")
highest_even(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Output
your maximum even number is: 444
[Program finished]
Sorting Depending on Highest Even Element
Code Syntax
def highest_even_list(*tuple):
lis = sorted(filter(lambda x: x % 2 == 0, tuple), reverse=True)
return print(f"Sorted List depending on The highest Even Elements:\n{lis}")
highest_even_list(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555)
Output
Sorted List depending on The highest Even Elements:
[444, 222, 12, 10, 8, 6, 4, 2]
[Program finished]
Using Kwargs for Reversing
You can also decide if you want to sort it ascending or descending using **kwargs
Code Syntax
def highest_even_list(*tuple, **kwargs):
lis = sorted(filter(lambda x: x % 2 == 0, tuple), **kwargs)
return print(f"Sorted List depending on The highest Even Elements:\n{lis}")
highest_even_list(1,2,3,4,5,6,7,8,9,10,11,12,111,222,444,555, reverse=True)
Output
Sorted List depending on The highest Even Elements:
[444, 222, 12, 10, 8, 6, 4, 2]
[Program finished]

How to perform a calculation n amount of times? [duplicate]

This question already has answers here:
'NoneType' object has no attribute 'append' python
(4 answers)
Closed 3 years ago.
I have a homework problem where we have to count the amount of rectangular blocks used in the construction of a pyramid design. The pyramid design consists of 'x' rows, 'y' columns and 'z' layers. For example if the values x = 2, y = 3, z = 1 were entered, the program would output 6, which would be the number of blocks. Every layer that comes after has one more row (x+1) and one more column(y+1). So if the values x = 2, y = 3, z = 2 were entered, 12 would be returned which is the number of total blocks and so on.
This is what I have so far but I keep getting an error:
def blocks(x,y,z):
if z == 1:
return x * y
else:
result = []
total = x * y #<--- initial calculation
for i in range(z):
total = ((x+1)*(y+1))
result = result.append(total)
print (blocks(2,3,4))
The error message I get is:
result = result.append(total)
AttributeError: 'NoneType' object has no attribute 'append'
list.append() returns None, so your reassignment:
result = result.append(total)
will reassign result to None on each iteration of your loop. Instead, remove the reassignment, since append modifys the existing list in place.
replace result = result.append(total)
with result.append(total)
when you append an object to a list, there is no need to set the result equal to a new list; it does the appending on the list in place.

From where this 2 came in output? Fibonacci series using python Lists

If you do not want to read this text, I have explained the problem in this Youtube video: https://youtu.be/Ekkkgjf0F_s
Following is the code that I am using to generate Fibonacci series using python
lists.
list1 = [0, 1]
x=1
while x <=2:
length = len(list1)
first =list1[length-2]
second =list1[length-1]
third = first + second
list1.append(third)
x+=1
print list1
When the while loop runs for the 1st iteration, it generates the upcoming element in series and stores in list exactly what it should do.
The list will now become:
list1 = [0,1,1]
But what confusing me is when the second iteration is made by while loop.
If you dry run the code, you will see that the code is outputting 2 (according to fibonacci series sequence, it is right)
but if we dry run the code, the 4th element should be 3 instead of 2
2nd interation, length = 3>>Dry RUN below:
3-2=1
3-1=2
1+2=3
list1 should be: [0,1,1,3]
But i am getting the output as:
list1=[0,1,1,2]
I can't understand , how this 2 came in output.
your list has len() of 3, and therefore your algorithm adds element 1 and 2 (which are both 1) together. that's why you get returned the 2.
EDIT: which is exactly how the Fibonacci-Series goes....
Code with comments as follows:
length = len(list1) #3
first =list1[length-2] #list on index 1 is value 1
second =list1[length-1] #list on index 2 is value 1
third = first + second # 1+1 = 2
list1.append(third) # 2 is appended
x+=1
print list1
you probably confuse the value on list index [1] with the actual difference between len of list 3 and 1.
When you list1 becomes [0,1,1], the len of list1 is 3.
Now try running the following:
length = len(list1) = 3
first = list1[length-2] = list1[3-2] = list1[1] = 1
second = list1[length-1] = list1[3-1] = list1[2] = 1
third = first + second = 1 + 1 = 2
Hence, it adds 2 to the list.

Iterate through 2D List, assign each value on a row in the list to a variable, repeat for each row - python

I have a list comprising a number of X,Y values
aList = [[1, 2],[3, 4],[5, 6],[7, 8]]
i.e. X = 1, Y = 2
I need to extract each X and Y value on a row separately, assign those values to an X and Y variable respectively, and then act on the X and Y values.
This should then loop to the next row where the same process would occur again. I'll use print instead of the excessive code that needs to occur after this loop.
i.e. loop starts, X is assigned 1, Y is assigned 2, X and Y are used as inputs in formula, loop ends (and repeat for the remaining values in this list)
aListLen = len(aList)
aListRows = len(aList)
aListCols = len(aList[0])
The following code only extracts values 1 by one in the list
for row in range(aListRows):
for column in range(aListCols):
X = aList[row][column]
print X
adding a Y variable as follows results in an error
for row in range(aListRows):
for column in range(aListCols):
X = a[row][column]
Y = a[row][column+1]
print X
print Y
Looking at it now, I'm not sure the following if/elif loop would work as the X and Y values need to go in a formula together.
I could add an if/elif statement under the 2nd loop, but I'd still need to have a way of forcing the 2nd loop to repeat. (Which brings us back to the original problem anyway)
for row in range(aListRows):
for column in range(aListCols):
if column == 0:
X = aList[row][column]
elif column == 1:
Y = aList[row][column]
How can I force the loop to restart once the X value has been provided?
I assume the loop would then repeat, this time providing the value for Y.
Is there a better way of doing this?
Should point out this is Python 2.7 (so I cannot use anything exclusive to Python 3)
You're looping over the indices of the inner list and adding 1 to them. This will cause an IndexError when column contains the value of aListCols, since len(a[row]) == column+1
I think you are looking for this:
In [17]: aList = [[1, 2],[3, 4],[5, 6],[7, 8]]
In [18]: for X,Y in aList:
....: print "X value is %s, Y value is %s" %(X, Y)
....:
X value is 1, Y value is 2
X value is 3, Y value is 4
X value is 5, Y value is 6
X value is 7, Y value is 8
To assign the variables instead of printing them you could do:
for X,Y in aList:
tempX = X
tempY = Y
At the first iteration tempX will have a value of 1, tempY will have a value of 2. At the second iteration tempX will be 3, tempY will be 4...
You could, instead of a loop, use a recursive function.
Basically, that is a function that calls itself. For example:
def myfunction():
(something happens that wants you to start the function over)
myfunction()
Hence, it will call the function again, forcing the code to go back to the top.

Categories

Resources