Reputation: 79
I'm writing some code that trims down a words in a list of string. if the last character of a word in the string is 't' or 's' it is removed and if the first character is 'x' it is removed.
words = ['bees', 'xerez']
should return:
['bee', 'erez']
So far my solution is:
trim_last = [x[:-1] for x in words if x[-1] == 's' or 't']
I think this trims the last characters fine. I then to trim the first characters if they are 'x' with this line:
trim_first = [x[1:] for x in trim_last if x[0] == 'x']
but this just returns an empty list, can i some how incorporate this into one working line?
Upvotes: 1
Views: 273
Reputation: 12679
Why you are using two list comprehension for that you can do with one list comprehension :
one line solution:
words = ['bees', 'xerez','hellot','xnewt']
print([item[:-1] if item.endswith('t') or item.endswith('s') else item for item in [item[1:] if item.startswith('x') else item for item in words]])
output:
['bee', 'erez', 'hello', 'new']
Explanation of above list comprehension :
final=[]
for item in words:
sub_list=[]
if item.endswith('t') or item.endswith('s'):
sub_list.append(item[:-1])
else:
sub_list.append(item)
for item in sub_list:
if item.startswith('x'):
final.append(item[1:])
else:
final.append(item)
print(final)
Upvotes: 0
Reputation: 1
You can try this code:
trim_last = [x.lstrip('x').rstrip('t').rstrip('s') for x in words]
Upvotes: 0
Reputation: 9532
If you are looking for a one-liner you can use some arithmetic to play with the list slicing:
words = ['bees', 'xerez', 'xeret']
[w[w[0] == 'x' : len(w) - int(w[-1] in 'st')] for w in words]
# output: ['bee', 'erez', 'ere']
Upvotes: 1
Reputation: 25980
Just to chime in - since this is in fact, a mapping:
map(lambda x: x[1:] if x[0] == 'x' else x, words)
Upvotes: 1
Reputation: 92884
In one step with re.sub()
function:
import re
words = ['bees', 'xerez']
result = [re.sub(r'^x|[ts]$', '', w) for w in words]
print(result)
The output:
['bee', 'erez']
Upvotes: 2
Reputation: 4770
You're doing a filter, not a mapping. The right way would be
trim_first = [x[1:] if x.startswith('x') else x for x in trim_last]
Also, your solution should not return an empty list since the filter would match on the second element
Upvotes: 3