optimus_prime optimus_prime - 3 years ago 101
Python Question

A list comprehension with two "fors" and a "if" condition

I have 2 lists:

>>> phrases = ['emp_sal','emp_addr']
>>> cols = ['emp_sal_total','emp_sal_monthly','emp_addr_primary','emp_ssn','emp_phone']


I am trying to use list comprehension and filter out cols such that only those values in cols should be picked that have a phrase emp_sal or emp_addr in them.

So, output should be:

['emp_sal_total','emp_sal_monthly','emp_addr_primary']


This is just a dummy example replicating the scenario. Actual example has a cols list of 180 odd columns.

Tried below solution:

new_cols = [c for c in cols if p for p in phrases in c]


It fails with:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not list


Below approach yields a blank list:

>>> [c for c in cols if p in c for p in phrases]
[]

Answer Source

You need to test if any string in phrases is in the current column your iterating over in cols. For this, use any():

[c for c in cols if any(c.startswith(p) for p in phrases)]

The problem with your method was that you were trying to use p before it was defined, which raises a NameError:

>>> [c for c in cols if p in c for p in phrases]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'p' is not defined

As noted in the comments by @Hamms, you can still use something similar to your method. You just need to have defined p before trying to use it:

>>> [c for c in cols for p in phrases if p in c]
['emp_sal_total', 'emp_sal_monthly', 'emp_addr_primary']
>>> 
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download