Reputation: 1466
Imagine you have a list of lists as follows:
list = [['Hello','Hello World','something else'],
['Hello','something'],
['somethings']
['Hello World','something else'],
['Hello','blabla','Hello World']]
I would like to remove the 'Hello' in the list if and only if 'Hello World' is in it.
What I have tried:
new_list = [elem.remove('Hello') for elem in lista if 'Hello' and 'Hello World' in elem]
However, I get the following error:
list.remove(x): x not in list
And my list becomes this:
[['Hello World', 'something else'],
['Hello', 'something'],
['somethings'],
['Hello World', 'something else'],
['Hello', 'blabla', 'Hello World']]
So it worked for the first row, but then it broke.
Extra points for computational efficiency!
Upvotes: 1
Views: 53
Reputation: 47790
The problem lies here:
if 'Hello' and 'Hello World' in elem
This does not work how you think it does. if 'Hello'
is a separate clause, which always evaluates to True
since 'Hello'
is not an empty string. You need to write out the full test both times:
if 'Hello' in elem and 'Hello World' in elem
Separately, writing this as a list comprehension doesn't quite make sense since list.remove
modifies the original list, and doesn't return anything. Your new_list
will just be full of None
. Just use a for
loop:
for sub_list in my_list: # also note, you should not use `list` as a variable name.
if 'Hello' in sub_list and 'Hello World' in sub_list:
sub_list.remove('Hello')
If you actually don't want to modify the original list / sub-lists, you'll need to create new lists explicitly instead of using remove
:
new_list = []
for sub_list in my_list:
if 'Hello World' in sub_list:
new_sub_list = [elem for elem in sub_list if elem != 'Hello']
else:
new_sub_list = sub_list[:] # make a copy to avoid referencing the original
new_list.append(new_sub_list)
This whole thing can also be written as a nested list-comprehension if you want:
new_list = [sub_list[:] if 'Hello World' not in sub_list else
[elem for elem in sub_list if elem != 'Hello']
for sub_list in my_list]
But in either case, I'd probably prefer the explicit for loop construction just for clarity.
Upvotes: 1
Reputation: 71451
You can use a an inner list comprehension to filter "hello"
values:
l = [['Hello','Hello World','something else'], ['Hello','something'], ['somethings'], ['Hello World','something else'],['Hello','blabla','Hello World']]
new_l = [[c for c in i if c != 'Hello'] if 'Hello World' in i else i for i in l]
Output:
[['Hello World', 'something else'], ['Hello', 'something'], ['somethings'], ['Hello World', 'something else'], ['blabla', 'Hello World']]
Upvotes: 1