user2436203
user2436203

Reputation: 35

filtering lists based on multiple conditions

I'm learning Python based on the list below I'd like to filter based on several different conditions and combine the results.

list_of_stuff = [
    "aus-airport-1",
    "aus-airport-2",
    "us-airport-1",
    "us-airport-2",
    "aus-ship-1",
    "us-ship-99",
    "nz-airport-1"
]

The program should be able to allow a user to:

A mock of my idea is below, I'm sure there must be a better pattern like map,filter,reduce or even the built in filter so looking for help on how to improve. The program will accept and users input and only filter if a filter type is specified. For example list_of_stuff --exclude_region nz --transport ship.

My mock attempt

def filter_transport(stuff,transport):
    if transport:
        if stuff.split("-")[1] == transport:
            return True
        else:
            return False
    else:
        return True    

def exclude_region(stuff,region):
    if region:
        if stuff.split("-")[0] ==region:
            return True
    else:
        return False    

def included_region(stuff,region):
    if region:
        if stuff.split("-")[0] ==region:
            return True
        else:
            return False
    else:
        return True    

def filters(stuff,transport=None,include_region=None,excluded_region=None):
    if( filter_transport(stuff,transport) and 
        included_region(stuff,include_region) and not exclude_region(stuff,excluded_region)  ):
        return True    


#give all airports excluding nz
stuff = [stuff for stuff in list_of_stuff if filters(stuff,transport="airport",excluded_region="nz")]
print (stuff)
#give all airports in aus
stuff = [stuff for stuff in list_of_stuff if filters(stuff,transport="airport",include_region="aus")]
print (stuff)
#give all ships
stuff = [stuff for stuff in list_of_stuff if filters(stuff,transport="ship")]
print (stuff)

Upvotes: 2

Views: 2074

Answers (4)

dani herrera
dani herrera

Reputation: 51655

You can filter your list:

list_of_stuff = [
    "aus-airport-1",
    "aus-airport-2",
    "us-airport-1",
    "us-airport-2",
    "aus-ship-1",
    "us-ship-99",
    "nz-airport-1"
]

is_airport = lambda x: "-airport-" in x
is_ship = lambda x: "-ship-" in x

airports_excluding_nz = lambda x: is_airport(x) and not x.startswith("nz-")
airports_in_aus = lambda x: is_airport(x) and x.startswith("nz-")
ships = lambda x: is_ship(x)

print ("all regions excluding nz:" , 
       ", ".join( filter(airports_excluding_nz , list_of_stuff) ) )
print ("all regions in aus:", 
       ", ".join( filter(airports_in_aus, list_of_stuff) ) )
print ("all ships:", 
       ", ".join( filter(ships, list_of_stuff) ) )

Check results:

all regions excluding nz aus-airport-1, aus-airport-2, us-airport-1, us-airport-2
all regions in aus nz-airport-1
all ships aus-ship-1, us-ship-99

Upvotes: 1

Prince Francis
Prince Francis

Reputation: 3097

We can filter it by using regex too as below

conditions

not contains region and contains transport

res = [k for k in list_of_stuff if bool(re.search('(?=.*-' + transport + '-.*)(^((?!' + region + '-).)*$)', k))]

full sample code is

import re
list_of_stuff = ["aus-airport-1",
    "aus-airport-2",
    "us-airport-1",
    "us-airport-2",
    "aus-ship-1",
    "us-ship-99",
    "nz-airport-1"]

region = 'aus'
transport = 'ship'
res = [k for k in list_of_stuff if bool(re.search('(?=.*-' + transport + '-.*)(^((?!' + region + '-).)*$)', k))]
print(res)

output is

['us-ship-99']

Upvotes: 0

andreihondrari
andreihondrari

Reputation: 5833

How about like this:

import argparse 

parser = argparse.ArgumentParser()
parser.add_argument("--exclude-region", dest="excluded_region", action="store")
parser.add_argument("--only-region", dest="only_region", action="store")
parser.add_argument("--transport", dest="transport", action="store")
args_space = parser.parse_args()


list_of_stuff = [
    "aus-airport-1",
    "aus-airport-2",
    "us-airport-1",
    "us-airport-2",
    "aus-ship-1",
    "us-ship-99",
    "nz-airport-1"
]


def exclude_by_country(country, elements):
    return filter(lambda x: x.split('-')[0] != country, elements)

def filter_by_country(country, elements):
    return filter(lambda x: x.split('-')[0] == country, elements)

def filter_by_type(vehicle_type, elements):
    return filter(lambda x: x.split('-')[1] == vehicle_type, elements)


results = list_of_stuff

if args_space.excluded_region:
    results = exclude_by_country(args_space.excluded_region, results)

if args_space.only_region:
    results = filter_by_country(args_space.only_region, results)

if args_space.transport:
    results = filter_by_type(args_space.transport, results)

print([x for x in results])

Upvotes: 0

Austin
Austin

Reputation: 26039

You can use three straight list-comprehensions:

lst = ["aus-airport-1","aus-airport-2","us-airport-1","us-airport-2","aus-ship-1","us-ship-99","nz-airport-1"]

splits = list(map(lambda x: x.split('-'), lst))

lst1 = [x for x in splits if x[1] == 'airport' and x[0] != 'nz']
print(f'All airports excluding nz: {lst1}')

lst2 = [x for x in splits if x[1] == 'airport' and x[0] == 'aus']
print(f'All airports in aus: {lst2}')

lst3 = [x for x in splits if x[1] == 'ship']
print(f'All ships: {lst3}')

Upvotes: 0

Related Questions