Smallest Number in a List - Python - python

I am trying to write a function that takes a list input and returns the index of the smallest number in that list.
For example,
minPos( [5,4,3,2,1] ) → 4
When I run my function, I get a List Index error, can someone please help? Thanks. I cannot use the built in function min().
def MinPos(L):
Subscript = 0
Hydrogen = 1
SmallestNumber = L[Subscript]
while L[Subscript] < len(L):
while L[Subscript] < L[Subscript + Hydrogen]:
Subscript += 1
return SmallestNumber
while L[Subscript] > L[Subscript + Hydrogen]:
Subscript += 1
return SmallestNumber
def main():
print MinPos( [-5,-4] )

Maybe something like this:
>>> def min_pos(L):
... min = None
... for i,v in enumerate(L):
... if min is None or min[1] > v:
... min = (i,v)
... return min[0] if min else None
>>> min_pos([1,3,4,5])
0
>>> min_pos([1,3,4,0,5])
3
Edit: Return None if empty list

Since you already know how to find the minimum value, you simply feed that value to the index() function to get the index of this value in the list. I.e,
>>> n = ([5,4,3,2,1])
>>> n.index(min(n))
4
This will return the index of the minimum value in the list. Note that if there are several minima it will return the first.

I would recommend use of for ... and enumarate():
data = [6, 3, 2, 4, 2, 5]
try:
index, minimum = 0, data[0]
for i, value in enumerate(data):
if value < minimum:
index, minimum = i, value
except IndexError:
index = None
print index
# Out[49]: 2
EDIT added guard against empty data

Related

Python Task "Even the last"

I have a task "You are given an array of integers. You should find the sum of the integers with even indexes (0th, 2nd, 4th...). Then multiply this summed number and the final element of the array together. Don't forget that the first element has an index of 0.
For an empty array, the result will always be 0 (zero).
Input: A list of integers.
Output: The number as an integer."
My solution is:
def checkio(array: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
summary = 0
if len(array) > 0:
for i in array:
if array.index(i) % 2 == 0:
summary += i
print('sum = ' + str(summary) + ' index = ' + str(array.index(i)))
res = summary * array[-1]
return res
else:
return 0
And when it doesnt work correct, when i print indexes to see whats wrong, i got that some index is missing (in this example 16th)
print(checkio([-37,-36,-19,-99,29,20,3,-7,-64,84,36,62,26,-76,55,-24,84,49,-65,41]))
Output:
sum = -37 index = 0
sum = -56 index = 2
sum = -27 index = 4
sum = -24 index = 6
sum = -88 index = 8
sum = -52 index = 10
sum = -26 index = 12
sum = 29 index = 14
sum = -36 index = 18
-1476
What is the reason?
The issue is that array.index() will return the first index of the value
You have a 84 at position 9, then when you call it on the second 84, the vall is the same array.index(84) so result is same : 9 and it won't count it
Use enumarate that make an iterator with both position and value
def checkio(array: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
summary = 0
if array: # true is non-empty
for i, value in enumerate(array):
if i % 2 == 0:
summary += value
print('sum =', summary,'index =', i)
res = summary * array[-1]
return res
return 0
As mentioned in the answer by #azro, the problem with your code has to do with array.index() always returning the first index of a given element in your list, so that it will return undesired results for duplicates.
enumerate() is one way to go, but there's still room for some optimization here. The following bit is verbose, since it will loop over all the elements, while we already know we only need elem 0, 2, etc.
for i, value in enumerate(array):
if i % 2 == 0:
We could just write:
array = [-37,-36,-19,-99,29,20,3,-7,-64,84,36,62,26,-76,55,-24,84,49,-65,41]
def checkio1(array: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
summary = 0
if array: # true is non-empty
for i in range(0,len(array),2): # 2 is the step, so we enter elem 0, 2, etc.
summary += array[i]
res = summary * array[-1]
return res
return 0
print(checkio1(array))
1968
Let me share two alternative methods as well.
using numpy:
import numpy as np
def checkio2(array: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
if not array:
return 0
arr = np.array(array)
return arr[np.arange(0,len(arr),2)].sum()*arr[-1]
print(checkio2(array))
1968
print(checkio2([]))
0
using itemgetter from the operator module:
from operator import itemgetter
def checkio3(array: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
if not array:
return 0
return sum(itemgetter(*range(0,len(array),2))(array))*array[-1]
print(checkio3(array))
1968
print(checkio3([]))
0
Here is my approach, use range(start: stop: step) to quickly select the numbers based on the even-indexes and avoid later repeatedly checking (modulus). This is just for another reference. All previous posts work great.
I don't like to use array here, since it has different meaning in Python.
def checkio(nums: list) -> int:
"""
sums even-indexes elements and multiply at the last
"""
if not nums: # not empty
return sum(nums[0::2]) * nums[-1] # . just rely on range slicing here & save some modulo computations later...
else:
return 0

Why am I getting a list index out of range error?

I'm not sure why I am getting the following error:
builtins.IndexError: list index out of range
at the following line (line 5):
C[A[key(a)]] == C[A[key(a)]] + 1
An example of input for this code would be A = [2, -2, 1] and key = lambda x: x**2, and in the loop on line 4-5, it takes the key of item at A[a] as the chosen index for array C, and increments the value at that index by 1. For example: C[A[key(0)]], or C[4], is 0, and it is incremented to 1.
def key_positions(A, key):
k = key(max(A, key = key))
C = [0] * (k+1)
for a in A:
C[A[key(a)]] == C[A[key(a)]] + 1
for i in range(0, k):
sum = C[i]
return C
You are trying to treat key(a) as an index into the list A. Neither a nor key(a) are valid indices in the range [0, len(A)].
If you wanted to count occurrences of key(a), just use that directly as an index into C:
def key_positions(A, key):
k = key(max(A, key = key))
C = [0] * (k+1)
for a in A:
C[key(a)] += 1
for i in range(0, k):
sum = C[i]
return C
I used += augmented assignment here rather than the more verbose C[key(a)] = C[key(a)] + 1; this saves re-executing the key() function each time.
Calculating the maximum k value is also simpler with:
k = max(key(a) for a in A)
Next, your loop with sum = C[i] is also nonsensical; the loop is redundant as you don't ever use sum and you could have used sum = C[-1] for all that the loop does.
The reason is that you access the List A = [2, -2, 1] with a index that is out of bounds of your list A.
For every iteration of your first for loop,
you calculates the square of a (through your key lamba) and this leads to the index error.
You have to make sure that you don't access the list A with index values that are bigger than the size of the List A.
For example:
for a in A:
# key(a) will be 4, 4, 1
# but for key(2) it will be 4
# and larger than the list A.
C[A[key(a)]] == C[A[key(a)]] + 1

Why is for loop not printing as expected in Python?

I am new to python. I was learning the syntax of the for loop in python as:
for var in list_name:
# do something
I took a list:
list = [1,2,3,4,5,6,7,8,9]
I wanted to double each of its elements, so I run a loop as:
for i in list :
index = list.index(i)
list[index] = 2*i
print(list)
Then it prints:
[16,2,12,4,10,6,14,8,18]
I am not getting why it is printing like this?
Let's run through the first few iterations of your loop.
Iteration 1: i is 1.
index = list.index(i)
list[index] = 2*i
index is 0, and list[0] is set to 2*i. The list now looks like [2, 2, 3, 4, 5, 6, 7, 8, 9].
Iteration 2: i is 2.
index = list.index(i)
list.index(2) finds the first occurrence of 2 in the list, which is at index 0! There's more than one 2, and you're not selecting the right one.
list[index] = 2*i
You double the wrong element!
This happens again on iterations 4, 6, and 8.
If you want to double the elements of a list, the easiest way is to make a new list with a list comprehension:
l = [2*i for i in l]
If you need the indices of the elements in a for loop, the best way is usually to enumerate the list:
for i, item in enumerate(l):
whatever()
Also, don't call your list list, or when you try to call the list function, you'll get a weird TypeError.
Your code doesn't work as you expected, because list.index will return the first index of the element in the list. So, if the same element occurs more than once, it will not work as you expected.
The best way to double elements is to use list comprehension, like this
my_list = [item * 2 for item in my_list]
If you want to use a for loop, you can use enumerate, like this
for index, current_num in enumerate(my_list):
my_list[index] = current_num * 2
This is ugly because we are modifying the list as we iterate it. So, don't do this. Instead you can do like this
for index in xrange(len(my_list)):
my_list[index] *= 2
list.index(i) returns the first index in the list where i is found.
thelist = [1,2,3,4,5,6,7,8,9]
> index = thelist.index(1)
> index = 0
> thelist[0] = 2
> index = thelist.index(2)
> index = 0
> thelist[0] = 2*2 = 4
> index = thelist.index(3)
> index = 2
> thelist[2] = 2*3 = 6
> index = thelist.index(4)
> index = 0
> thelist[0] = 2*4 = 8
> index = thelist.index(5)
> index = 4
> thelist[4] = 2*5 = 10
> index = thelist.index(6)
> index = 2
> thelist[2] = 2*6 = 12
> index = thelist.index(7)
> index = 6
> thelist[6] = 2*7 = 14
> index = thelist.index(8)
> index = 0
> thelist[0] = 2*8 = 16
> index = thelist.index(9)
> index = 8
> thelist[8] = 2*9 = 18
and the rest of the elements will remain unaltered.
Also, it is incorrect to use a keyword as a variable name. You should NOT use list as a variable name.
print map(lambda x: x*2, my_list)
Because you're altering the wrong element of your list each time. The syntax for i in list set the value of one element of the list, not an index.
In fact, you shouldn't altering the list you're working on but creating a new list. A correct way would be:
new_list = []
for i in list:
new_list.append(2*i)
# Or even, with a list comprehension
new_list = [i*2 for i in list]
print(new_list)

counting odd numbers in a list python

This is a part of my homework assignment and im close to the final answer but not quite yet. I need to write a function that counts odd numbers in a list.
Create a recursive function count_odd(l) which takes as its only argument a list of integers. The function will return a count of the number of list elements that are odd, i.e., not evenly divisible by 2.\
>>> print count_odd([])
0
>>> print count_odd([1, 3, 5])
3
>>> print count_odd([2, 4, 6])
0
>>> print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
8
Here is what i have so far:
#- recursive function count_odd -#
def count_odd(l):
"""returns a count of the odd integers in l.
PRE: l is a list of integers.
POST: l is unchanged."""
count_odd=0
while count_odd<len(l):
if l[count_odd]%2==0:
count_odd=count_odd
else:
l[count_odd]%2!=0
count_odd=count_odd+1
return count_odd
#- test harness
print count_odd([])
print count_odd([1, 3, 5])
print count_odd([2, 4, 6])
print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
Can u help explain what im missing. The first two test harness works fine but i cant get the final two. Thanks!
Since this is homework, consider this pseudo-code that just counts a list:
function count (LIST)
if LIST has more items
// recursive case.
// Add one for the current item we are counting,
// and call count() again to process the *remaining* items.
remaining = everything in LIST except the first item
return 1 + count(remaining)
else
// base case -- what "ends" the recursion
// If an item is removed each time, the list will eventually be empty.
return 0
This is very similar to what the homework is asking for, but it needs to be translate to Python and you must work out the correct recursive case logic.
Happy coding.
def count_odd(L):
return (L[0]%2) + count_odd(L[1:]) if L else 0
Are slices ok? Doesn't feel recursive to me, but I guess the whole thing is kind of against usual idioms (i.e. - recursion of this sort in Python):
def countOdd(l):
if l == list(): return 0 # base case, empty list means we're done
return l[0] % 2 + countOdd(l[1:]) # add 1 (or don't) depending on odd/even of element 0. recurse on the rest
x%2 is 1 for odds, 0 for evens. If you are uncomfortable with it or just don't understand it, use the following in place of the last line above:
thisElement = l[0]
restOfList = l[1:]
if thisElement % 2 == 0: currentElementOdd = 0
else: currentElementOdd = 1
return currentElementOdd + countOdd(restOfList)
PS - this is pretty recursive, see what your teacher says if you turn this in =P
>>> def countOdd(l):
... return fold(lambda x,y: x+(y&1),l,0)
...
>>> def fold(f,l,a):
... if l == list(): return a
... return fold(f,l[1:],f(a,l[0]))
All of the prior answers are subdividing the problem into subproblems of size 1 and size n-1. Several people noted that the recursive stack might easily blow out. This solution should keep the recursive stack size at O(log n):
def count_odd(series):
l = len(series) >> 1
if l < 1:
return series[0] & 1 if series else 0
else:
return count_odd(series[:l]) + count_odd(series[l:])
The goal of recursion is to divide the problem into smaller pieces, and apply the solution to the smaller pieces. In this case, we can check if the first number of the list (l[0]) is odd, then call the function again (this is the "recursion") with the rest of the list (l[1:]), adding our current result to the result of the recursion.
def count_odd(series):
if not series:
return 0
else:
left, right = series[0], series[1:]
return count_odd(right) + (1 if (left & 1) else 0)
Tail recursion
def count_odd(integers):
def iter_(lst, count):
return iter_(rest(lst), count + is_odd(first(lst))) if lst else count
return iter_(integers, 0)
def is_odd(integer):
"""Whether the `integer` is odd."""
return integer % 2 != 0 # or `return integer & 1`
def first(lst):
"""Get the first element from the `lst` list.
Return `None` if there are no elements.
"""
return lst[0] if lst else None
def rest(lst):
"""Return `lst` list without the first element."""
return lst[1:]
There is no tail-call optimization in Python, so the above version is purely educational.
The call could be visualize as:
count_odd([1,2,3]) # returns
iter_([1,2,3], 0) # could be replaced by; depth=1
iter_([2,3], 0 + is_odd(1)) if [1,2,3] else 0 # `bool([1,2,3])` is True in Python
iter_([2,3], 0 + True) # `True == 1` in Python
iter_([2,3], 1) # depth=2
iter_([3], 1 + is_odd(2)) if [2,3] else 1
iter_([3], 1 + False) # `False == 0` in Python
iter_([3], 1) # depth=3
iter_([], 1 + is_odd(3)) if [3] else 1
iter_([], 2) # depth=4
iter_(rest([]), 2 + is_odd(first([])) if [] else 2 # bool([]) is False in Python
2 # the answer
Simple trampolining
To avoid 'max recursion depth exceeded' errors for large arrays all tail calls in recursive functions can be wrapped in lambda: expressions; and special trampoline() function can be used to unwrap such expressions. It effectively converts recursion into iterating over a simple loop:
import functools
def trampoline(function):
"""Resolve delayed calls."""
#functools.wraps(function)
def wrapper(*args):
f = function(*args)
while callable(f):
f = f()
return f
return wrapper
def iter_(lst, count):
#NOTE: added `lambda:` before the tail call
return (lambda:iter_(rest(lst), count+is_odd(first(lst)))) if lst else count
#trampoline
def count_odd(integers):
return iter_(integers, 0)
Example:
count_odd([1,2,3])
iter_([1,2,3], 0) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([2,3], 0+is_odd(1)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([3], 1+is_odd(2)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([], 1+is_odd(3))
2 # callable(2) is False
I would write it like this:
def countOddNumbers(numbers):
sum = 0
for num in numbers:
if num%2!=0:
sum += numbers.count(num)
return sum
not sure if i got your question , but as above something similar:
def countOddNumbers(numbers):
count=0
for i in numbers:
if i%2!=0:
count+=1
return count
Generator can give quick result in one line code:
sum((x%2 for x in nums))

Find the most common element in a list

What is an efficient way to find the most common element in a Python list?
My list items may not be hashable so can't use a dictionary.
Also in case of draws the item with the lowest index should be returned. Example:
>>> most_common(['duck', 'duck', 'goose'])
'duck'
>>> most_common(['goose', 'duck', 'duck', 'goose'])
'goose'
A simpler one-liner:
def most_common(lst):
return max(set(lst), key=lst.count)
Borrowing from here, this can be used with Python 2.7:
from collections import Counter
def Most_Common(lst):
data = Counter(lst)
return data.most_common(1)[0][0]
Works around 4-6 times faster than Alex's solutions, and is 50 times faster than the one-liner proposed by newacct.
On CPython 3.6+ (any Python 3.7+) the above will select the first seen element in case of ties. If you're running on older Python, to retrieve the element that occurs first in the list in case of ties you need to do two passes to preserve order:
# Only needed pre-3.6!
def most_common(lst):
data = Counter(lst)
return max(lst, key=data.get)
With so many solutions proposed, I'm amazed nobody's proposed what I'd consider an obvious one (for non-hashable but comparable elements) -- [itertools.groupby][1]. itertools offers fast, reusable functionality, and lets you delegate some tricky logic to well-tested standard library components. Consider for example:
import itertools
import operator
def most_common(L):
# get an iterable of (item, iterable) pairs
SL = sorted((x, i) for i, x in enumerate(L))
# print 'SL:', SL
groups = itertools.groupby(SL, key=operator.itemgetter(0))
# auxiliary function to get "quality" for an item
def _auxfun(g):
item, iterable = g
count = 0
min_index = len(L)
for _, where in iterable:
count += 1
min_index = min(min_index, where)
# print 'item %r, count %r, minind %r' % (item, count, min_index)
return count, -min_index
# pick the highest-count/earliest item
return max(groups, key=_auxfun)[0]
This could be written more concisely, of course, but I'm aiming for maximal clarity. The two print statements can be uncommented to better see the machinery in action; for example, with prints uncommented:
print most_common(['goose', 'duck', 'duck', 'goose'])
emits:
SL: [('duck', 1), ('duck', 2), ('goose', 0), ('goose', 3)]
item 'duck', count 2, minind 1
item 'goose', count 2, minind 0
goose
As you see, SL is a list of pairs, each pair an item followed by the item's index in the original list (to implement the key condition that, if the "most common" items with the same highest count are > 1, the result must be the earliest-occurring one).
groupby groups by the item only (via operator.itemgetter). The auxiliary function, called once per grouping during the max computation, receives and internally unpacks a group - a tuple with two items (item, iterable) where the iterable's items are also two-item tuples, (item, original index) [[the items of SL]].
Then the auxiliary function uses a loop to determine both the count of entries in the group's iterable, and the minimum original index; it returns those as combined "quality key", with the min index sign-changed so the max operation will consider "better" those items that occurred earlier in the original list.
This code could be much simpler if it worried a little less about big-O issues in time and space, e.g....:
def most_common(L):
groups = itertools.groupby(sorted(L))
def _auxfun((item, iterable)):
return len(list(iterable)), -L.index(item)
return max(groups, key=_auxfun)[0]
same basic idea, just expressed more simply and compactly... but, alas, an extra O(N) auxiliary space (to embody the groups' iterables to lists) and O(N squared) time (to get the L.index of every item). While premature optimization is the root of all evil in programming, deliberately picking an O(N squared) approach when an O(N log N) one is available just goes too much against the grain of scalability!-)
Finally, for those who prefer "oneliners" to clarity and performance, a bonus 1-liner version with suitably mangled names:-).
from itertools import groupby as g
def most_common_oneliner(L):
return max(g(sorted(L)), key=lambda(x, v):(len(list(v)),-L.index(x)))[0]
What you want is known in statistics as mode, and Python of course has a built-in function to do exactly that for you:
>>> from statistics import mode
>>> mode([1, 2, 2, 3, 3, 3, 3, 3, 4, 5, 6, 6, 6])
3
Note that if there is no "most common element" such as cases where the top two are tied, this will raise StatisticsError on Python
<=3.7, and on 3.8 onwards it will return the first one encountered.
Without the requirement about the lowest index, you can use collections.Counter for this:
from collections import Counter
a = [1936, 2401, 2916, 4761, 9216, 9216, 9604, 9801]
c = Counter(a)
print(c.most_common(1)) # the one most common element... 2 would mean the 2 most common
[(9216, 2)] # a set containing the element, and it's count in 'a'
If they are not hashable, you can sort them and do a single loop over the result counting the items (identical items will be next to each other). But it might be faster to make them hashable and use a dict.
def most_common(lst):
cur_length = 0
max_length = 0
cur_i = 0
max_i = 0
cur_item = None
max_item = None
for i, item in sorted(enumerate(lst), key=lambda x: x[1]):
if cur_item is None or cur_item != item:
if cur_length > max_length or (cur_length == max_length and cur_i < max_i):
max_length = cur_length
max_i = cur_i
max_item = cur_item
cur_length = 1
cur_i = i
cur_item = item
else:
cur_length += 1
if cur_length > max_length or (cur_length == max_length and cur_i < max_i):
return cur_item
return max_item
This is an O(n) solution.
mydict = {}
cnt, itm = 0, ''
for item in reversed(lst):
mydict[item] = mydict.get(item, 0) + 1
if mydict[item] >= cnt :
cnt, itm = mydict[item], item
print itm
(reversed is used to make sure that it returns the lowest index item)
Sort a copy of the list and find the longest run. You can decorate the list before sorting it with the index of each element, and then choose the run that starts with the lowest index in the case of a tie.
A one-liner:
def most_common (lst):
return max(((item, lst.count(item)) for item in set(lst)), key=lambda a: a[1])[0]
I am doing this using scipy stat module and lambda:
import scipy.stats
lst = [1,2,3,4,5,6,7,5]
most_freq_val = lambda x: scipy.stats.mode(x)[0][0]
print(most_freq_val(lst))
Result:
most_freq_val = 5
# use Decorate, Sort, Undecorate to solve the problem
def most_common(iterable):
# Make a list with tuples: (item, index)
# The index will be used later to break ties for most common item.
lst = [(x, i) for i, x in enumerate(iterable)]
lst.sort()
# lst_final will also be a list of tuples: (count, index, item)
# Sorting on this list will find us the most common item, and the index
# will break ties so the one listed first wins. Count is negative so
# largest count will have lowest value and sort first.
lst_final = []
# Get an iterator for our new list...
itr = iter(lst)
# ...and pop the first tuple off. Setup current state vars for loop.
count = 1
tup = next(itr)
x_cur, i_cur = tup
# Loop over sorted list of tuples, counting occurrences of item.
for tup in itr:
# Same item again?
if x_cur == tup[0]:
# Yes, same item; increment count
count += 1
else:
# No, new item, so write previous current item to lst_final...
t = (-count, i_cur, x_cur)
lst_final.append(t)
# ...and reset current state vars for loop.
x_cur, i_cur = tup
count = 1
# Write final item after loop ends
t = (-count, i_cur, x_cur)
lst_final.append(t)
lst_final.sort()
answer = lst_final[0][2]
return answer
print most_common(['x', 'e', 'a', 'e', 'a', 'e', 'e']) # prints 'e'
print most_common(['goose', 'duck', 'duck', 'goose']) # prints 'goose'
Building on Luiz's answer, but satisfying the "in case of draws the item with the lowest index should be returned" condition:
from statistics import mode, StatisticsError
def most_common(l):
try:
return mode(l)
except StatisticsError as e:
# will only return the first element if no unique mode found
if 'no unique mode' in e.args[0]:
return l[0]
# this is for "StatisticsError: no mode for empty data"
# after calling mode([])
raise
Example:
>>> most_common(['a', 'b', 'b'])
'b'
>>> most_common([1, 2])
1
>>> most_common([])
StatisticsError: no mode for empty data
Simple one line solution
moc= max([(lst.count(chr),chr) for chr in set(lst)])
It will return most frequent element with its frequency.
You probably don't need this anymore, but this is what I did for a similar problem. (It looks longer than it is because of the comments.)
itemList = ['hi', 'hi', 'hello', 'bye']
counter = {}
maxItemCount = 0
for item in itemList:
try:
# Referencing this will cause a KeyError exception
# if it doesn't already exist
counter[item]
# ... meaning if we get this far it didn't happen so
# we'll increment
counter[item] += 1
except KeyError:
# If we got a KeyError we need to create the
# dictionary key
counter[item] = 1
# Keep overwriting maxItemCount with the latest number,
# if it's higher than the existing itemCount
if counter[item] > maxItemCount:
maxItemCount = counter[item]
mostPopularItem = item
print mostPopularItem
ans = [1, 1, 0, 0, 1, 1]
all_ans = {ans.count(ans[i]): ans[i] for i in range(len(ans))}
print(all_ans)
all_ans={4: 1, 2: 0}
max_key = max(all_ans.keys())
4
print(all_ans[max_key])
1
#This will return the list sorted by frequency:
def orderByFrequency(list):
listUniqueValues = np.unique(list)
listQty = []
listOrderedByFrequency = []
for i in range(len(listUniqueValues)):
listQty.append(list.count(listUniqueValues[i]))
for i in range(len(listQty)):
index_bigger = np.argmax(listQty)
for j in range(listQty[index_bigger]):
listOrderedByFrequency.append(listUniqueValues[index_bigger])
listQty[index_bigger] = -1
return listOrderedByFrequency
#And this will return a list with the most frequent values in a list:
def getMostFrequentValues(list):
if (len(list) <= 1):
return list
list_most_frequent = []
list_ordered_by_frequency = orderByFrequency(list)
list_most_frequent.append(list_ordered_by_frequency[0])
frequency = list_ordered_by_frequency.count(list_ordered_by_frequency[0])
index = 0
while(index < len(list_ordered_by_frequency)):
index = index + frequency
if(index < len(list_ordered_by_frequency)):
testValue = list_ordered_by_frequency[index]
testValueFrequency = list_ordered_by_frequency.count(testValue)
if (testValueFrequency == frequency):
list_most_frequent.append(testValue)
else:
break
return list_most_frequent
#tests:
print(getMostFrequentValues([]))
print(getMostFrequentValues([1]))
print(getMostFrequentValues([1,1]))
print(getMostFrequentValues([2,1]))
print(getMostFrequentValues([2,2,1]))
print(getMostFrequentValues([1,2,1,2]))
print(getMostFrequentValues([1,2,1,2,2]))
print(getMostFrequentValues([3,2,3,5,6,3,2,2]))
print(getMostFrequentValues([1,2,2,60,50,3,3,50,3,4,50,4,4,60,60]))
Results:
[]
[1]
[1]
[1, 2]
[2]
[1, 2]
[2]
[2, 3]
[3, 4, 50, 60]
Here:
def most_common(l):
max = 0
maxitem = None
for x in set(l):
count = l.count(x)
if count > max:
max = count
maxitem = x
return maxitem
I have a vague feeling there is a method somewhere in the standard library that will give you the count of each element, but I can't find it.
This is the obvious slow solution (O(n^2)) if neither sorting nor hashing is feasible, but equality comparison (==) is available:
def most_common(items):
if not items:
raise ValueError
fitems = []
best_idx = 0
for item in items:
item_missing = True
i = 0
for fitem in fitems:
if fitem[0] == item:
fitem[1] += 1
d = fitem[1] - fitems[best_idx][1]
if d > 0 or (d == 0 and fitems[best_idx][2] > fitem[2]):
best_idx = i
item_missing = False
break
i += 1
if item_missing:
fitems.append([item, 1, i])
return items[best_idx]
But making your items hashable or sortable (as recommended by other answers) would almost always make finding the most common element faster if the length of your list (n) is large. O(n) on average with hashing, and O(n*log(n)) at worst for sorting.
>>> li = ['goose', 'duck', 'duck']
>>> def foo(li):
st = set(li)
mx = -1
for each in st:
temp = li.count(each):
if mx < temp:
mx = temp
h = each
return h
>>> foo(li)
'duck'
I needed to do this in a recent program. I'll admit it, I couldn't understand Alex's answer, so this is what I ended up with.
def mostPopular(l):
mpEl=None
mpIndex=0
mpCount=0
curEl=None
curCount=0
for i, el in sorted(enumerate(l), key=lambda x: (x[1], x[0]), reverse=True):
curCount=curCount+1 if el==curEl else 1
curEl=el
if curCount>mpCount \
or (curCount==mpCount and i<mpIndex):
mpEl=curEl
mpIndex=i
mpCount=curCount
return mpEl, mpCount, mpIndex
I timed it against Alex's solution and it's about 10-15% faster for short lists, but once you go over 100 elements or more (tested up to 200000) it's about 20% slower.
def most_frequent(List):
counter = 0
num = List[0]
for i in List:
curr_frequency = List.count(i)
if(curr_frequency> counter):
counter = curr_frequency
num = i
return num
List = [2, 1, 2, 2, 1, 3]
print(most_frequent(List))
Hi this is a very simple solution, with linear time complexity
L = ['goose', 'duck', 'duck']
def most_common(L):
current_winner = 0
max_repeated = None
for i in L:
amount_times = L.count(i)
if amount_times > current_winner:
current_winner = amount_times
max_repeated = i
return max_repeated
print(most_common(L))
"duck"
Where number, is the element in the list that repeats most of the time
numbers = [1, 3, 7, 4, 3, 0, 3, 6, 3]
max_repeat_num = max(numbers, key=numbers.count) *# which number most* frequently
max_repeat = numbers.count(max_repeat_num) *#how many times*
print(f" the number {max_repeat_num} is repeated{max_repeat} times")
def mostCommonElement(list):
count = {} // dict holder
max = 0 // keep track of the count by key
result = None // holder when count is greater than max
for i in list:
if i not in count:
count[i] = 1
else:
count[i] += 1
if count[i] > max:
max = count[i]
result = i
return result
mostCommonElement(["a","b","a","c"]) -> "a"
The most common element should be the one which is appearing more than N/2 times in the array where N being the len(array). The below technique will do it in O(n) time complexity, with just consuming O(1) auxiliary space.
from collections import Counter
def majorityElement(arr):
majority_elem = Counter(arr)
size = len(arr)
for key, val in majority_elem.items():
if val > size/2:
return key
return -1
def most_common(lst):
if max([lst.count(i)for i in lst]) == 1:
return False
else:
return max(set(lst), key=lst.count)
def popular(L):
C={}
for a in L:
C[a]=L.count(a)
for b in C.keys():
if C[b]==max(C.values()):
return b
L=[2,3,5,3,6,3,6,3,6,3,7,467,4,7,4]
print popular(L)

Categories

Resources