How to write a filtering function in Python

I have a list of football matches in the following format:

# HomeTeam, AwayTeam, HomeScore, AwayScore, HomeShots, AwayShots
[['Bayer 04', 'Werder Bremen', 2, 2, 21, 10]
 ['Paderborn', 'RB Leipzig', 2, 3, 8, 18]
 ['Koln', 'Augsburg', 1, 1, 13, 11]]

Suppose I want to extract only those matches, which meet some criterias, for example:

While filtering a list by a single criteria is straigtforward, for example extract the matches with more than 3 goals scored:

def moreThan3Goals(matches):
        result = []
        [result.append(match) for match in matches if match[2] + match[3] > 3]
        return result

It is not clear how to write a function which takes an arbitrary number of conditions and extract those matches which meet all the criterias.

Upvotes: 1

Views: 78

Answers (1)

Alexander
Alexander

Reputation: 109526

You may want to consider using namedtuple to make the functions readable.

from collections import namedtuple

# Convert raw data to list of named tuples.
col_names = ['HomeTeam', 'AwayTeam', 'HomeScore', 'AwayScore', 'HomeShots', 'AwayShots']
Match = namedtuple('Match', col_names)
raw_data = [
    ['Bayer 04', 'Werder Bremen', 2, 2, 21, 10],
    ['Paderborn', 'RB Leipzig', 2, 3, 8, 18],
    ['Koln', 'Augsburg', 1, 1, 13, 11]
]
data = [Match(*m) for m in raw_data]
>>> data
[Match(HomeTeam='Bayer 04', AwayTeam='Werder Bremen', HomeScore=2, AwayScore=2, HomeShots=21, AwayShots=10),
 Match(HomeTeam='Paderborn', AwayTeam='RB Leipzig', HomeScore=2, AwayScore=3, HomeShots=8, AwayShots=18),
 Match(HomeTeam='Koln', AwayTeam='Augsburg', HomeScore=1, AwayScore=1, HomeShots=13, AwayShots=11)]

Then create your arbitrary rules using lambda functions:

rule_1 = lambda m: m.HomeTeam == 'Bayer 04' and (m.HomeShots + m.AwayShots) > 25
rule_2 = lambda m: m.AwayTeam in {'RB Leipzig', 'Koln'}
rule_3 = lambda m: m.AwayScore > m.HomeScore

Now you can use a conditional list comprehension to match all the rules, converting the named tuple back to a list:

[list(m) for m in data 
 if all([rule_1(m), rule_2(m), rule_3(m)])]

Or by creating groups of rules:

rule_set_1 = [rule_1, rule_2, rule_3]
[list(m) for m in data 
 if all([rule(m) for rule in rule_set_1])]

Upvotes: 1

Related Questions