Home > database >  Return a list where any string in one list starts with any string in another
Return a list where any string in one list starts with any string in another

Time:07-02

In Python I'm attempting to use a list comprehension to create a list where any string in one list starts with any string in another.

For example, say I have a list of three names Alan, Bob and Carl. I wish to return a list of names that start with any string from another list, this time containing Bo, Da and Fr. There for I'd expect only ['Bob'] to be returned.

However, using the following example I'm seeing all of the names returned.

>>> starts_with=('Bo', 'Da', 'Fr')
>>> names = ['Alan', 'Bob', 'Carl']
>>> [n for n in names if [n.startswith(s) for s in starts_with]]
['Alan', 'Bob', 'Carl']

My issue seems to be that the inner list comprehension is returning a list of boolean values, so the list that is being checked by the if in the main list comprehension is never empty.

>>> starts_with=('Bo', 'Da', 'Fr')
>>> ['Alan'.startswith(s) for s in starts_with]
[False, False, False]
>>> ['Bob'.startswith(s) for s in starts_with]
[True, False, False]
>>> ['Carl'.startswith(s) for s in starts_with]
[False, False, False]

How can I amend my code so that only ['Bob'] is returned?

CodePudding user response:

Use any(), which is a builtin function that returns True if any element of an input iterable is true:

>>> starts_with=('Bo', 'Da', 'Fr')
>>> names = ['Alan', 'Bob', 'Carl']
>>> [n for n in names if any(n.startswith(s) for s in starts_with)]
['Bob']

CodePudding user response:

Simple and compact solution

[n for n in names for sw in starts_with if n.startswith(sw)]

As David asked why not use any instead :

Unraveling Samwise answer

[n for n in names if any(n.startswith(s) for s in starts_with)]

would be

for n in names:
    for s in starts_with:
        [add s to temp list say temp]
    for t in temp:
        if(t): # if t is true
            [add n to result list]

CodePudding user response:

You can avoid using any() with a simple double for loop comprehension:

starts_with=['Bo', 'Da', 'Fr']
names = ['Alan', 'Bob', 'Carl']


out = [i for i in names for j in starts_with if i.startswith(j)]
print(out)

['Bob']

  • Related