Given the following list my_list = [ ['red', 'yellow', 'green'], ['red', 'yellow', 'green'], ['red', 'green', 'red']]
, I want to find the element which appears at most. I have implemented a brute-force mathod together with a new list and a dictionary to hold the values for each element but the efficiency is not satisfactory. Which would be the best way to implement this search ? I am using Python 3.
Asked
Active
Viewed 2,053 times
1
-
1What do you mean by "brute-force"? It's not like there is a magic algorithm out there that can count elements in a list without iterating over it. – DeepSpace Jan 19 '18 at 13:46
-
I used 3 for loops. Copied all different elements in a new `list` and then used one `for` loop to keep track of each item in my new list and two more nested `for` loops for the given list. – Jan 19 '18 at 13:49
3 Answers
3
my_list = [ ['red', 'yellow', 'green'], ['red', 'yellow', 'green'], ['red', 'green', 'red']]
new_list = [k for v in my_list for k in v]
from collections import Counter
c = Counter(new_list)
print c.most_common(1)
>>> [('red', 4)]

Veera Balla Deva
- 790
- 6
- 19
-
1For sake of memory, use a generator instead of `new_list`: `print(Counter(element for sublist in my_list for element in sublist).most_common(1))` – DeepSpace Jan 19 '18 at 14:01
1
You can flatten the nested list and apply the max
function:
my_list = [ ['red', 'yellow', 'green'], ['red', 'yellow', 'green'], ['red', 'green', 'red']]
new_list = [i for x in my_list for i in x]
max_val = max(new_list, key=lambda x:new_list.count(x))
Output:
'red'

Ajax1234
- 69,937
- 8
- 61
- 102
-
`new_list` is just a waste of memory. You can just keep a dictionary in memory and count as you go. – DeepSpace Jan 19 '18 at 13:45
-
@DeepSpace your solution would be more efficient, but how exactly would that save space? – Ajax1234 Jan 19 '18 at 13:46
-
-
@Ajax1234 `new_list` is a waste of memory since it is an unnecessary flattened version of `my_list`. It can be turned into a generator at least. – DeepSpace Jan 19 '18 at 13:52
-
`from collections import Counter ; print(Counter(element for sublist in my_list for element in sublist).most_common(1)) ; # [('red', 4)]` – DeepSpace Jan 19 '18 at 13:56
0
You can flatten your list with itertools.chain.from_iterable
, then use a collections.defaultdict
to store the counts, and getting the max key is easy from there:
from collections import defaultdict
from operator import itemgetter
from itertools import chain
my_list = [['red', 'yellow', 'green'], ['red', 'yellow', 'green'], ['red', 'green', 'red']]
d = defaultdict(int)
for word in chain.from_iterable(my_list):
d[word] += 1
print(max(d.items(), key = itemgetter(1))[0])
# red

RoadRunner
- 25,803
- 6
- 42
- 75