Search code examples
pythonlistif-statementlambdapython-itertools

How to use index with the itertools function in Python


I have a list which contains multimple lists inside it and it looks like this:

import itertools

stand_city = 11
stand_liverpool = 6.5

premier_league = [
             ['A1','Manchester City', '10,1', 'Aguero'],
             ['A2','Manchester City', '11,2', 'Mahrez'],
             ['A3','Manchester City', '13,5', 'Sterling'],
             ['B1','Liverpool', '4,5', 'Mane'],
             ['B2','Liverpool', '5,6', 'Salah'],
             ['B3','Liverpool', '7,2', 'Jota']]

Now for every list I want to get the last value before it exceeds either stand_city or stand_liverpool. Depending on index[1] in the lists. If its Manchester City I need it to use stand_city, if Liverpool I want it to use stand_liverpool. I want those values to be stored in a new list.

This is my code:

new_list  = []
for key,sublists in itertools.groupby(premier_league,lambda y:y[0]):
    club = (list(sublists)[0][1])
    if club == 'Manchester City':
        v=[] 
        for v in itertools.takewhile(lambda x:float(x[-2].replace(",","."))<stand_city ,sublists):
            pass
        if v: 
            x = v[-1]
            new_list.append(x)
    elif club == 'Liverpool':
        v=[] 
        for v in itertools.takewhile(lambda x:float(x[-2].replace(",","."))<stand_liverpool ,sublists):
            pass
        if v: 
            x = v[-2]
            new_list.append(x)
            
print(new_list) 

This is my output:

[]

This is my desired output:

10,1
5,6

Solution

  • I have done some small modifications to your code to get the result you want.

    stand_city = 11
    stand_liverpool = 6.5
    
    premier_league = [
                 ['A1','Manchester City', '10,1', 'Aguero'],
                 ['A2','Manchester City', '11,2', 'Mahrez'],
                 ['A3','Manchester City', '13,5', 'Sterling'],
                 ['B1','Liverpool', '4,5', 'Mane'],
                 ['B2','Liverpool', '5,6', 'Salah'],
                 ['B3','Liverpool', '7,2', 'Jota']]
    
    res = []
    for g, value in groupby(premier_league, key = lambda x:x[1]): # group by according to index 1
        less_than = [] # temporary list to hold all values less than your threshold for a particular group
        for i in value: # iterate thorugh the values in each group
            float_i = float(i[2].replace(',', '.')) # convert index 2 to float
            to_compare = stand_city if g == 'Manchester City' else stand_liverpool
            if float_i < to_compare: # compare `float_i` with either `stand_city` or `stand_liverpool` based on group
                less_than.append(i[2]) # add all values that meet the condition to a temp list
        res.extend(less_than[-1:]) # take only the last element from the list for each group, `[-1:]` is done to prevent cases where `less_than` is an empty list
    print(res) # ['10,1', '5,6']
    

    Or in a shorter way

    from itertools import groupby
    res = []
    for g, value in groupby(premier_league, key = lambda x:x[1]):
        last = [x[2] for x in value if float(x[2].replace(',', '.')) <= (stand_city if g == 'Manchester City' else stand_liverpool)][-1:]
        res.extend(last)
    
    print(res) # ['10,1', '5,6']
    

    Fixed OP's code to work

    import itertools
    
    new_list  = []
    for key,sublists in itertools.groupby(premier_league,lambda y:y[1]):
        if key == 'Manchester City':
            v=[] 
            for v in itertools.takewhile(lambda x:float(x[-2].replace(",","."))<stand_city ,sublists):
                pass
            if v: 
                x = v[-2]
                new_list.append(x)
        elif key == 'Liverpool':
            v=[] 
            for v in itertools.takewhile(lambda x:float(x[-2].replace(",","."))<stand_liverpool ,sublists):
                pass
            if v: 
                x = v[-2]
                new_list.append(x)
                
    print(new_list)