2

What is the Pythonic/quick way to search for a partial string in an array and then remove that string from the array?
(I can do it with a simple loop and IF IN and rebuild two array in the loop, Asking if there is a Pythonic way/function to do this)

Example:

array = ['rule1','rule2','exception[type_a]','rule3','exception[type_b]']
res(,)=remove_exceptions(array,'exception')
print(res[0]) >>> ['rule1','rule2','rule3']
print(res[1]) >>> ['exception[type_a]','exception[type_b]']
6
  • You want to just remove them or you want to extract them from your list? Commented Aug 25, 2016 at 17:11
  • Iterating over your list and creating two new lists in the loop suite is Pythonic. If the list elements are as you represented, you could make use of the str.startswith method. Commented Aug 25, 2016 at 17:20
  • @Kasramvd either would work for me Commented Aug 25, 2016 at 17:29
  • @ItayMoav-Malimovka Check out my answer. Commented Aug 25, 2016 at 17:35
  • @Kasramvd while this is what I currently (almost) use, my question was if there is a built in function/language construct (Pythonic way) to do it more efficiently (either less text/faster). Commented Aug 25, 2016 at 17:37

5 Answers 5

2
>>> [x for x in array if 'exception' not in x]
['rule1', 'rule2', 'rule3']
>>> [x for x in array if 'exception' in x]
['exception[type_a]', 'exception[type_b]']

See also: Python: split a list based on a condition?

Sign up to request clarification or add additional context in comments.

Comments

1

If you want to separate your items you can do it with one loop and by preserving the items in a dictionary:

>>> d = {}
>>> for i in array:
...     if 'exception' in i:
...         d.setdefault('exception', []).append(i)
...     else:
...         d.setdefault('other', []).append(i)
... 
>>> 
>>> d
{'exception': ['exception[type_a]', 'exception[type_b]'], 'other': ['rule1', 'rule2', 'rule3']}

You can access to separated items by calling the values of the dictionary:

>>> d.values()
[['exception[type_a]', 'exception[type_b]'], ['rule1', 'rule2', 'rule3']]

Comments

1

Seriously, just use a for loop, you're trying to create two lists so a single comprehension won't do (i.e the top solution so far iterates twice over the same list).

Create two lists and append to them conditionally:

l1 = list()
l2 = list()
for i in array:
    l1.append(i) if 'exception' in i else l2.append(i)

print(l1)
['exception[type_a]', 'exception[type_b]']
print(l2)
['rule1', 'rule2', 'rule3']

1 Comment

"a single comprehension won't do" I feel like there must be a way to do this with co-routines and a couple of deques, so that you only pass over the list once, but use the minimal possible additional memory. As against that, like you say, seriously just use a for loop. Especially when the desired result is two lists, just make two lists :-)
0

For list-of-strings array and thing-to-exclude target:

List comprehensions work:

result = [s for s in array if target not in s]

Or a generator comprehension for the same:

result = (s for s in array if target not in s)

(in is effectively a contains operator, and not in is the inverse.)

Alternately, use the filter() built-in with a lambda:

result = filter(lambda x: target not in x,
                array)

Either one returns a new object, rather than modifying your original list. The list comprehension returns a list, filter() returns a generator but you can wrap the call in list() if you need random access.

Comments

0

You may use in-built filter with lambda function to achieve this as:

>>> my_array = array = ['rule1','rule2','exception[type_a]','rule3','exception[type_b]']
>>> my_string = 'exception'
>>> filter(lambda x: my_string not in x, my_array)
['rule1', 'rule2', 'rule3']

14 Comments

What makes this Pythonic?
It is Pythonic because of the usage of inbuilt functions that Python provides and perfectly suits the requirement. That says, there is no need to do list comprehension. Now my question to you: What makes it non Pythonic?
Comprehensions are (arguably) more readable. See http://stackoverflow.com/a/3013722/1936320
I was curious why this was pythonic or more pythonic than just iterating over the list with a for loop and testing the elements in order to separate them.
In an ideal world you'd write filter(not x.contains, my_array), but they're not offering us that ;-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.