Check if second max number is duplicated (python) - python

I'm learning python, I want to check if the second largest number is duplicated in a list. I've tried several ways, but I couldn't. Also, I have searched on google for this issue, I have got several answers to get/print 2nd largest number from a list but I couldn't find any answer to check if the 2nd largest number is duplicated. can anyone help me, please?
Here is my sample list:
list1 = [5, 6, 9, 9, 11]
list2 = [8, 9, 13, 14, 14]

Here is a 1-liner:
>>> list1 = [5, 6, 9, 9, 11]
>>> list1.count(sorted(list1)[-2]) > 1
True
or using heapq
>>> import heapq
>>> list1 = [5, 6, 9, 9, 11]
>>> list1.count(heapq.nlargest(2, list1)[1]) > 1
True

This is a simple algorithm:
Makes values unique
Sort your list by max value
Takes the second element
Check how many occurences of this elemnt exists in list
Code:
list1 = [5, 6, 9, 9, 11]
list2 = [8, 9, 13, 14, 14]
def check(data):
# 1. Make data unique
unique = list(set(data))
# 2. Sort by value
sorted_data = sorted(unique, reverse=True)
# 3. Takes the second element
item = sorted_data[1]
# 4. Check occurences
if data.count(item) > 1:
return True
else:
return False
print(check(list1))
print(check(list2))
Ouput
True
False

collections.Counter with sorted offers one solution:
from collections import Counter
lst1 = [5, 6, 9, 9, 11]
lst2 = [8, 9, 13, 14, 14]
res1 = sorted(Counter(lst1).items(), key=lambda x: -x[0])[1] # (9, 2)
res2 = sorted(Counter(lst2).items(), key=lambda x: -x[0])[1] # (13, 1)
The result is a tuple of second largest item and its count. It is then simple to check if the item is duplicated, e.g. res1[1] > 1.

Here is my proposal
li = [5, 6, 9, 9, 11]
li_uniq = list(set(li)) # list's elements are uniquified
li_uniq_sorted = sorted(li_uniq) # sort in ascending order
second_largest = li_uniq_sorted[-2] # get the 2nd largest -> 9
li.count(second_largest) # -> 2 (duplicated if > 1)

Related

Access any element in a list that has a 4 in it and add 1

If I have the list
a = [1, 7, 21,19, 8, 14, 104]
I want to add 1 to any element that contains the number 4. SO the output would be
a = [1,8, 21,19, 8, 15, 105]
With a conditional expression and comprehension it is easy:
>>> a = [1, 7, 21,19, 8, 14, 104]
>>> [e+1 if '4' in str(e) else e for e in a]
[1, 7, 21, 19, 8, 15, 105]
Explanation:
[e for e in a] loops over your list element by element and produces a new list based on that;
str() turns the integer into a string so you can test if '4' is in the number;
The Python keyword in tests to see if '4' is in the string;
Either add +1 or not based on that conditional test.
Try this
import random
arr = []
for i in range(5):
arr.append(random.randint(1, 5))
print(arr)

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???

How to loop through a list where data points are dependent on each other?

I have a list, a = [5, 4, 9, 3, 6, 6, 8, 2], and I essentially want to sum the first three numbers, and that sum will be the first value in the new list. The next value in the new list will be the sum of 4, 9, and 3...etc. etc. How to loop this in Python?
list slicing is a good method.
all you need to do is travese from start index to end index-2 , ( can make sum of last 3 element and when you reach second last or last ement you wont be able to take 3 elemnts)
here you can take 3 elemnts and using list slicing, slice list from the
current index to next 3 index ie a[i:i+3] where [i,i+3) is range. then on that new list performing sum operation and appending the reuslt to final list.
a = [5, 4, 9, 3, 6, 6, 8, 2]
res=[]
for i in range(len(a)-2):
res.append(sum(a[i:i+3]))
print(res)
output
[18, 16, 18, 15, 20, 16]
One liner:
list(map(sum, zip(a, a[1:], a[2:])))
Output:
[18, 16, 18, 15, 20, 16]
So you are creating the required sublists of the numbers you want to add up and then you sum each sublist using the high-order function map.
If I understood what you want:
b = [sum(a[i : i+3]) for i in range(0, len(a)-2)]

Python list slicing

I'm not able understand what to do here. Can someone help.
I've a few lists:
array = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]
output = []
intermediate = []
slice is a list of indices I need to get from slicing array. interval is a list of indices used to stop the slicing when slice[i] is interval[j] where i and j are looping variables.
I need to form a list of lists from array based on slice and intervals based on the condition that when slice[i] is not interval[j]
intermediate =intermediate + array[slice[i]:slice[i+1]+1]
here in my case:
when slice[i] and interval[j] are equal for value 12. So I need to form a list of lists from array
intermediate = array[slice[0]:slice[0+1]+1] + array[slice[2]:slice[2+1]+1] + array[slice[4]:slice[4+1]+1]
which is
intermediate = array[2:(4+1)] + array[6:(8+1)] + array[10:(12+1)]
and when slice[i] is interval[j] output = output + intermediate and the slicing is continued.
output = output + [intermediate]
which is
output = output + [array[2:(4+1)] + array[6:(8+1)] + array[10:(12+1)]]
now the next value in interval is 17 so till we have 17 in slice we form another list from array[slice[6]:slice[6+1]+1] and add this to the output. This continues.
The final output should be:
output = [array[slice[0]:slice[0+1]+1] + array[slice[2]:slice[2+1]+1] + array[slice[4]:slice[4+1]+1] , array[slice[6]:slice[6+1]+1], array[slice[8]:slice[8+1]+1]]
which is
output = [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
A straightforward solution:
array_ = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice_ = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]
output = []
intermediate = []
for i in range(0, len(slice_), 2):
intermediate.extend(array_[slice_[i]:slice_[i+1]+1])
if slice_[i+1] in intervals:
output.append(intermediate)
intermediate = []
print output
# [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
I have changed some variable names to avoid conflicts.
On large data, you may convert intervals to a set.
Here is a recursive solution which goes through the index once and dynamically check if the index is within the intervals and append the sliced results to a list accordingly:
def slicing(array, index, stops, sliced):
# if the length of index is smaller than two, stop
if len(index) < 2:
return
# if the first element of the index in the intervals, create a new list in the result
# accordingly and move one index forward
elif index[0] in stops:
if len(index) >= 3:
sliced += [[]]
slicing(array, index[1:], stops, sliced)
# if the second element of the index is in the intervals, append the slice to the last
# element of the list, create a new sublist and move two indexes forward accordingly
elif index[1] in stops:
sliced[-1] += array[index[0]:(index[1]+1)]
if len(index) >= 4:
sliced += [[]]
slicing(array, index[2:], stops, sliced)
# append the new slice to the last element of the result list and move two index
# forward if none of the above conditions satisfied:
else:
sliced[-1] += array[index[0]:(index[1]+1)]
slicing(array, index[2:], stops, sliced)
sliced = [[]]
slicing(array, slice_, intervals, sliced)
sliced
# [[2, 3, 4, 5, 6, 7, 8, 9, 10], [12, 13, 14], [15, 16, 17]]
Data:
array = [7,8,2,3,4,10,5,6,7,10,8,9,10,4,5,12,13,14,1,2,15,16,17]
slice_ = [2, 4, 6, 8, 10, 12, 15, 17, 20, 22]
intervals = [12, 17, 22]

Changing a list item without changing original values

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

Categories