Is there an easy way in python of creating a list of substrings from a list of strings?
Example:
original list: ['abcd','efgh','ijkl','mnop']
list of substrings: ['bc','fg','jk','no']
I know this could be achieved with a simple loop but is there an easier way in python (Maybe a one-liner)?
Use slicing and list comprehension:
>>> lis = ['abcd','efgh','ijkl','mnop']
>>> [ x[1:3] for x in lis]
['bc', 'fg', 'jk', 'no']
Slicing:
>>> s = 'abcd'
>>> s[1:3] #return sub-string from 1 to 2th index (3 in not inclusive)
'bc'
With a mix of slicing and list comprehensions you can do it like this
listy = ['abcd','efgh','ijkl','mnop']
[item[1:3] for item in listy]
>> ['bc', 'fg', 'jk', 'no']
You can use a one-liner list-comprehension.
Using slicing, and relative positions, you can then trim the first and last character in each item.
>>> l = ['abcd','efgh','ijkl','mnop']
>>> [x[1:-1] for x in l]
['bc', 'fg', 'jk', 'no']
If you are doing this many times, consider using a function:
def trim(string, trim_left=1, trim_right=1):
return string[trim_left:-trim_right]
def trim_list(lst, trim_left=1, trim_right=1):
return [trim(x, trim_left, trim_right) for x in lst]
>>> trim_list(['abcd','efgh','ijkl','mnop'])
['bc', 'fg', 'jk', 'no']
If you want to do this in one line you could try this:
>>> map(lambda s: s[1:-1], ['abcd','efgh','ijkl','mnop'])
Related
Given the list ['a','ab','abc','bac'], I want to compute a list with strings that have 'ab' in them. I.e. the result is ['ab','abc']. How can this be done in Python?
This simple filtering can be achieved in many ways with Python. The best approach is to use "list comprehensions" as follows:
>>> lst = ['a', 'ab', 'abc', 'bac']
>>> [k for k in lst if 'ab' in k]
['ab', 'abc']
Another way is to use the filter function. In Python 2:
>>> filter(lambda k: 'ab' in k, lst)
['ab', 'abc']
In Python 3, it returns an iterator instead of a list, but you can cast it:
>>> list(filter(lambda k: 'ab' in k, lst))
['ab', 'abc']
Though it's better practice to use a comprehension.
[x for x in L if 'ab' in x]
# To support matches from the beginning, not any matches:
items = ['a', 'ab', 'abc', 'bac']
prefix = 'ab'
filter(lambda x: x.startswith(prefix), items)
Tried this out quickly in the interactive shell:
>>> l = ['a', 'ab', 'abc', 'bac']
>>> [x for x in l if 'ab' in x]
['ab', 'abc']
>>>
Why does this work? Because the in operator is defined for strings to mean: "is substring of".
Also, you might want to consider writing out the loop as opposed to using the list comprehension syntax used above:
l = ['a', 'ab', 'abc', 'bac']
result = []
for s in l:
if 'ab' in s:
result.append(s)
mylist = ['a', 'ab', 'abc']
assert 'ab' in mylist
If I have a list of lists, how can I remove every element from each list, except for the last element? (Keeping only the last element from each list and deleting all other elements before it)
If my list of lists looks like this:
lst = [['Hello', 'World'], ['Hello', 'E', 'Planet'], ['Planet', 'World', 'Earth']]
I want my outputted list to look like this:
lst_new = [['World'], ['Planet'], ['Earth']]
So far, my code looks like this, but the problem I'm facing is that it is eliminating the last list entirely from the list of lists:
lst_new = [x for x in lst if x != lst.remove(lst[len(lst)-1])]
print(lst_new)
#[['Hello', 'World'], ['Hello', 'E', 'Planet']]
Where am I going wrong? Would appreciate any help - thanks!
Just use simple indexing:
>>> lst_new = [ [x[-1]] for x in lst ]
>>> lst_new
[['World'], ['Planet'], ['Earth']]
You can use slicing:
lst = [['Hello', 'World'], ['Hello', 'E', 'Planet'], ['Planet', 'World', 'Earth']]
lst_new = [sublst[-1:] for sublst in lst]
print(lst_new) # [['World'], ['Planet'], ['Earth']]
I have a list of strings and currently I can search for one substring at the time:
str = ['abc', 'efg', 'xyz']
[s for s in str if "a" in s]
which correctly returns
['abc']
Now let's say I have a list of substrings instead:
subs = ['a', 'ef']
I want a command like
[s for s in str if anyof(subs) in s]
which should return
['abc', 'efg']
>>> s = ['abc', 'efg', 'xyz']
>>> subs = ['a', 'ef']
>>> [x for x in s if any(sub in x for sub in subs)]
['abc', 'efg']
Don't use str as a variable name, it's a builtin.
Gets a little convoluted but you could do
[s for s in str if any([sub for sub in subs if sub in s])]
Simply use them one after the other:
[s for s in str for r in subs if r in s]
>>> r = ['abc', 'efg', 'xyz']
>>> s = ['a', 'ef']
>>> [t for t in r for x in s if x in t]
['abc', 'efg']
I still like map and filter, despite what is being said against and how comprehension can always replace a map and a filter. Hence, here is a map + filter + lambda version:
print filter(lambda x: any(map(x.__contains__,subs)), s)
which reads:
filter elements of s that contain any element from subs
I like how this uses words that carry a strong semantic meaning, rather than only if, for, in
I have a list of strings like
['ABC', 'DEF', 'GHIJ']
and I want a list of strings containing the first letter of each string, i.e.
['A', 'D', 'G'].
I thought about doing that using map and the function that returns the first element of a list: my_list[0]. But how can I pass this to map?
Thanks.
you can try
In [14]: l = ['ABC', 'DEF', 'GHIJ']
In [15]: [x[0] for x in l]
Out[15]: ['A', 'D', 'G']
You should use a list comprehension, like #avasal since it's more pythonic, but here's how to do it with map:
>>> from operator import itemgetter
>>> L = ['ABC', 'DEF', 'GHIJ']
>>> map(itemgetter(0), L)
['A', 'D', 'G']
use list comprehension like so:
results = [i[0] for i in mySrcList]
One way:
l1=['ABC', 'DEF', 'GHIJ']
l1=map(lambda x:x[0], l1)
a=['ABC','DEF','GHI']
b=[]
for i in a:
b.append(i[0])
b is the array you need.
Try this.
>>> myArray=['ABC', 'DEF', 'GHIJ']
>>> newArray=[]
>>> for i in map(lambda x:x[0],myArray):
... newArray.append(i)
...
>>> print(newArray)
['A', 'D', 'G']
I have a list of curse words I want to match against other list to remove matches. I normally use list.remove('entry') on an individual basis, but looping through a list of entries against another list - then removing them has me stumped. Any ideas?
Using filter:
>>> words = ['there', 'was', 'a', 'ffff', 'time', 'ssss']
>>> curses = set(['ffff', 'ssss'])
>>> filter(lambda x: x not in curses, words)
['there', 'was', 'a', 'time']
>>>
It could also be done with list comprehension:
>>> [x for x in words if x not in curses]
Use sets.
a=set(["cat","dog","budgie"])
b=set(["horse","budgie","donkey"])
a-b
->set(['dog', 'cat'])