Getting indexes of all max values in a list [duplicate] - python

This question already has answers here:
How to find all positions of the maximum value in a list?
(18 answers)
Closed 3 years ago.
Is there any way in Python to get all indexes of elements which contain max value of a list?
I've tried this:
list = [1, 3, 2, 2, 1, 1, 1, 2, 3, 2, 1, 1, 1, 3, 1, 1, 3]
m = list.index (max(list))
But this returns only the first index of all of those which have max value.

Try this :
l = [1, 3, 2, 2, 1, 1, 1, 2, 3, 2, 1, 1, 1, 3, 1, 1, 3]
mx = max(l)
m = [i for i,j in enumerate(l) if j==mx]
OUTPUT :
[1, 8, 13, 16]

You can compute the max then use a list comprehension to get the indices where the max is found:
l = [1, 3, 2, 2, 1, 1, 1, 2, 3, 2, 1, 1, 1, 3, 1, 1, 3]
x = max(l)
m = [i for i in range(len(l)) if l[i] == x]
print(m)
Output:
[1, 8, 13, 16]

Related

Check if python list elemnts respect a pattern

I have a list that looks like :
L = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1]
I want to check if the sequence 2-1-2 is always respected or I have an outlier somewhere .
Is there a simple way to do this with python ?
from itertools import cycle
L = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
seq = cycle([2, 1])
for idx, el in enumerate(L):
if not el == next(seq):
raise ValueError(f"Sequence not followed at index {idx}")
What does "2-1-2 is always respected" mean, precisely?
I assume you want to check if Lis an alternating sequence of 2 and 1, starting with 2.
That's easy to check:
def check(L):
if len(L) < 3:
return False
even_indices_all_two = set(L[::2]) == {2}
odd_indices_all_one = set(L[1::2]) == {1}
return even_indices_all_two and odd_indices_all_one and L[-1] == 2
If you don't require L to end with 2, remove the and L[-1] == 2.
If you wonder about the many colons, check this post to understand slicing.
I use the set to check if a sequence contains only one distinct item.

Get counters within cycles

Say I have a list as follows:
list_sequences = [1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 2, 3, 2, 3, 1]
I want to create another list with the count of the occurrences, but the occurrence of 2 and 3 is reset after an occurrence of 1.
Something like:
occurrence_list = [1, 1, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 2, 3, 3, 4, 4, 4]
is there a simple pythonic way to do so?
You can use a defaultdict to keep account of what is going on:
from collections import defaultdict
list_sequences = [1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 2, 3, 2, 3, 1]
def make_occurrence(seq):
counter = defaultdict(int)
occurrence = []
for item in seq:
count = counter[item] + 1
if item == 1:
counter.clear()
counter[item] = count
occurrence.append(count)
return occurrence
print(make_occurrence(list_sequences))
Output as requested

how to sort in array index to index

Hey everyone how can I sort array index to index.
So I have code here
a = [0, 1, 2, 3, 4, 4, 3, 2, 1, 0, 4, 3, 2, 1, 0, 0, 1, 2, 3, 4]
how can i sort to?
[0, 4, 1, 3, 2, 2, 3, 1, 4, 0, 4, 0, 3, 1, 2, 2, 1, 3, 0, 4]
this is my idea
I could be wrong, but it sounds like you would like to return a list that is sorted like this:
[first_item, last_item, second_item, second_to_last_item, third_item, third_to_last_item,...]
I don't know of a one-line way to do that, but here's one way you could do it:
import numpy as np
a = [0, 1, 2, 3, 7] # length of list is an odd number
# create indexes that are all positive
index_values = np.repeat(np.arange(0, len(a)//2 + 1), 2) # [0,0,1,1,.....]
# make every other one negative
index_values[::2] *= -1 #[-0, 0, -1, 1, ....]
# return a[i]
[a[i] for i in index_values[1:(len(a)+1)]]
### Output: [0, 7, 1, 3, 2]
It also works for lists with even length:
a = [0, 1, 2, 3, 7, 5] # list length is an even number
index_values = np.repeat(np.arange(0, len(a)//2 + 1), 2) # [0,0,1,1,.....]
index_values[::2] *= -1 #[-0, 0, -1, 1, ....]
[a[i] for i in index_values[1:(len(a)+1)]]
### Output: [0, 5, 1, 7, 2, 3]
Here’s an almost one liner (based on #Callin’s sort method) for those that want one and that can’t/don’t want to use pandas:
from itertools import zip_longest
def custom_sort(a):
half = len(a)//2
return [n for fl in zip_longest(a[:half], a[:half-1:-1]) for n in fl if n is not None])
Examples:
custom_sort([0, 1, 2, 3, 7])
#[0, 7, 1, 3, 2]
custom_sort([0, 1, 2, 3, 7, 5])
#[0, 5, 1, 7, 2, 3]
This can be done in one line, although you’d be repeating the math to find the halfway point
[n for x in zip_longest(a[:len(a)//2], a[:(len(a)//2)-1:-1]) for n in x if n is not None]
Sometimes we want to sort in place, that is without creating a new list. Here is what I came up with
l=[1,2,3,4,5,6,7]
for i in range(1, len(l), 2):
l.insert(i, l.pop())

Repetition in Python for each element of list

I have a list a = [3,7,4]
I want to generate a list repetition of a sequence generated from each element of list like that:
b = [1,1,1,2,2,2,2,2,2,2,3,3,3,3]
Try like this.
result = []
for i,j in enumerate(a):
result += [i+1 for n in range(j)]
Result
[1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3]
input:
a = [3,7,4]
b = [x for x in range(len(a)+1)[1::] for j in range(a[x-1])]
result:
[1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3]

Combinations with limited repeats in Python

I know how to get ALL combinations of a list in Python with itertools, but what if I want to limit the amount of repeats?
So, if I have [1, 2, 3, 4, 5]
But I want to limit combinations to only 3 repeats of each item (with a fixed length of the final list, say 10):
[1, 1, 1, 2, 3, 3, 5, 5, 5, 4]
[1, 2, 3, 3, 3, 4, 5, 5, 4, 4]
[4, 4, 1, 1, 1, 5, 2, 2, 2, 3]
and so on. How do I do this?
This would work:
import random
L = [1, 2, 3, 4, 5]
L3 = L * 3
random.shuffle(L3)
L3[:10]
I don't know if there is a more elegant way but that seems to work:
from itertools import combinations_with_replacement
a = [1, 2, 3, 4, 5] # can contain letters as well
all_combinations = combinations_with_replacement(a, 10)
filtered_results = []
for current in all_combinations:
throw_away = False
for item in current:
if current.count(item) > 3:
throw_away = True
break
if not throw_away:
filtered_results.append( current )
for j in filtered_results:
print(j)
You could do it the following way: Use [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5] and use itertools.combination(the list from above, 10). That would mean that each element occurs at most three times in a resulting list.
Example with smaller list:
Edited to ensure every combination occurs exactly once, the combinations occur in random order and, finally, every combination has a random order.
Also incorporated the idea of Mike Müller to just multiply the list by 3.
import itertools
import random
combinations = set()
for c in itertools.combinations(sorted([1, 2, 3] * 3), 5):
combinations.add(c)
shuffledCombinations = list(combinations)
random.shuffle(shuffledCombinations)
for combination in shuffledCombinations:
copiedCombination = list(combination)
random.shuffle(copiedCombination)
print copiedCombination
which will give:
[2, 1, 3, 2, 2]
[2, 2, 1, 1, 2]
[3, 3, 3, 1, 2]
[2, 2, 3, 2, 3]
[1, 2, 3, 1, 2]
[1, 1, 1, 2, 3]
[2, 1, 1, 1, 2]
[3, 3, 1, 1, 1]
[1, 3, 3, 3, 1]
[3, 2, 3, 2, 3]
[3, 2, 1, 2, 3]
[1, 1, 2, 3, 3]

Categories

Resources