Sort a string in the list alphabetacaly - python

i have the following list:
strs = ["tea","tea","tan","ate","nat","bat"]
i want to sort the strings in that list to be like that:
strs = ["aet","aet","ant","aet","ant","abt"]
how i can do this ?
Thanks

Try like below:
>>> [''.join(sorted(s)) for s in strs]
['aet', 'aet', 'ant', 'aet', 'ant', 'abt']
# Or
>>> list(map(''.join, map(sorted, strs)))
['aet', 'aet', 'ant', 'aet', 'ant', 'abt']

out = []
for val in strs:
out.append("".join(sorted(list(val))))
print(out)

Related

strip all strings in list of specific character

I have been looking for an answer to this for a while but keep finding answers about stripping a specific string from a list.
Let's say this is my list of strings
stringList = ["cat\n","dog\n","bird\n","rat\n","snake\n"]
But all list items contain a new line character (\n)
How can I remove this from all the strings within the list?
Use a list comprehension with rstrip():
stringList = ["cat\n","dog\n","bird\n","rat\n","snake\n"]
output = [x.rstrip() for x in stringList]
print(output) # ['cat', 'dog', 'bird', 'rat', 'snake']
If you really want to target a single newline character only at the end of each string, then we can get more precise with re.sub:
stringList = ["cat\n","dog\n","bird\n","rat\n","snake\n"]
output = [re.sub(r'\n$', '', x) for x in stringList]
print(output) # ['cat', 'dog', 'bird', 'rat', 'snake']
By applying the method strip (or rstrip) to all terms of the list with map
out = list(map(str.strip, stringList))
print(out)
or with a more rudimental check and slice
strip_char = '\n'
out = [s[:-len(strip_char)] if s.endswith(strip_char) else s for s in stringList]
print(out)
Since you can use an if to check if a new line character exists in a string, you can use the code below to detect string elements with the new line character and replace those characters with empty strings
stringList = ["cat\n","dog\n","bird\n","rat\n","snake\n"]
nlist = []
for string in stringList:
if "\n" in string:
nlist.append(string.replace("\n" , ""))
print(nlist)
You could also use map() along with str.rstrip:
>>> string_list = ['cat\n', 'dog\n', 'bird\n', 'rat\n', 'snake\n']
>>> new_string_list = list(map(str.rstrip, string_list))
>>> new_string_list
['cat', 'dog', 'bird', 'rat', 'snake']

Want to reverse my String location and special character should be there as it is

I've a String as Input like
input = 'apple&&bat&&&cat&&dog&elephant'
and i want to reverse the words and special character should be remains same in their place.
Output - 'elephant&&dog&&&cat&&bat&apple'
Exactly, i don't know in which approach i have to solve this problem.
But, yes i've tried this
with this i got the reverse word but how to place the '&' in their respective position i don't know.
input = 'apple&&bat&&&cat&&dog&elephant'
ab = input.split('&')[::-1]
print ab
output
['elephant', 'dog', '', 'cat', '', '', 'bat', '', 'apple']
But my output should be
'elephant&&dog&&&cat&&bat&apple'
First get separate lists of the words and special marks using re module:
In [2]: import re
In [4]: words = re.findall(r'\w+', input)
In [6]: words
Out[6]: ['apple', 'bat', 'cat', 'dog', 'elephant']
In [7]: special = re.findall(r'\W+', input)
In [8]: special
Out[8]: ['&&', '&&&', '&&', '&']
Then reverse the words list:
In [11]: rwords = words[::-1]
In [12]: rwords
Out[12]: ['elephant', 'dog', 'cat', 'bat', 'apple']
Finally, combine each word with the corresponding mark. Please note that I expand the special list by one empty string to make the lists the same length. The final operation is one line of code:
In [15]: ''.join(w + s for w, s in zip(rwords, special + ['']))
Out[15]: 'elephant&&dog&&&cat&&bat&apple'
Here is one solution to the problem that uses only the basic concepts. It navigates the split list from both the left and the right and swaps each pair of encountered words.
s = 'apple&&bat&&&cat&&dog&elephant'
words = s.split('&')
idx_left = 0
idx_right = len(words) - 1
while idx_left < idx_right:
while not words[idx_left]:
idx_left += 1
while not words[idx_right]:
idx_right -= 1
words[idx_left], words[idx_right] = words[idx_right], words[idx_left] # Swap words
idx_left += 1
idx_right -= 1
output = '&'.join(words)
The result is
'elephant&&dog&&&cat&&bat&apple'
Another more advanced approach is to use groupby and list slicing:
from itertools import groupby
# Split the input string into the list
# ['apple', '&&', 'bat', '&&&', 'cat', '&&', 'dog', '&', 'elephant']
words = [''.join(g) for _, g in groupby(s, lambda c: c == '&')]
n = len(words)
words[::2] = words[n-n%2::-2] # Swapping (assume the input string does not start with a separator string)
output = ''.join(words)
Another regex solution:
>>> import re
>>> # Extract the "words" from the string.
>>> words = re.findall(r'\w+', s)
>>> words
['apple', 'bat', 'cat', 'dog', 'elephant']
>>> # Replace the words with formatting placeholders ( {} )
>>> # then format the resulting string with the words in
>>> # reverse order
>>> re.sub(r'\w+', '{}', s).format(*reversed(words))
'elephant&&dog&&&cat&&bat&apple'

print a sublist that contains all strings in another list, without necessarily being a direct match

search_terms = ['word','cow','horse']
library = [['desk','chair','lamp'],['cow','horse','word 223','barn']]
I want to be able to print all list(s) in library that contain ALL of the terms in search_terms.
so using the above list of search_terms would print the second sublist in library even though 'word 223' just contains 'word', but is not a direct match.
I will not always have the same number of strings...
Thanks for anyone who is willing to help me!
and thanks to falsetru for helping me with my first question!
To get your hits, use a list comprehension:
search_terms = ['word', 'cow', 'horse']
library = [['desk', 'chair', 'lamp'],
['cow', 'horse', 'word 223', 'barn']]
hits = [l for l in library if
all(any(t in s for s in l)
for t in search_terms)]
This works as follows
for each sub-list l in your library;
for all terms t in search_terms;
if any of the strings s in l contains it;
Keep l in the new list hits.
>>> search_terms = ['word','cow','horse']
>>> library = [['desk','chair','lamp'],['cow','horse','word 223','barn']]
>>> from itertools import chain
>>> list(chain(*library))
['desk', 'chair', 'lamp', 'cow', 'horse', 'word 223', 'barn']
>>> [word for word in search_terms if word in list(chain(*library))]
['cow', 'horse']
>>> [l for l in library if any(word for word in search_terms if word in l)]
[['cow', 'horse', 'word 223', 'barn']]

Groupby the list according to category

my code gives me output as a list
def extractKeywords():
<code>
return list
list = []
data = extractKeywords()
for x in range(0,5):
get = data[0][x]
list.append(get)
print list12
Output list is
['LION', 'tv', 'TIGER', 'keyboard', 'cd-writer','ELEPHANT']
How can i categorize this list into two groups like ( Expected output)
Animals = ['LION', 'TIGER', 'ELEPHANT']
Electronics = ['tv', 'keyboard', 'cd-writer']
All animals are in Capital letter and Electronics are in small letters
This solution uses itertools.groupby to avoid traversing the list twice.
>>> from itertools import groupby
>>> data = ['LION', 'tv', 'TIGER', 'keyboard', 'cd-writer','ELEPHANT']
>>> # upper case letters have lower `ord` values than lower case letters
>>> sort_by_case = sorted(data, key=lambda word: ord(word[0]))
>>> sort_by_case
['ELEPHANT', 'LION', 'TIGER', 'cd-writer', 'keyboard', 'tv']
>>> # group the words according to whether their first letter is upper case or not
>>> group_by_case = groupby(sort_by_case, lambda word: word[0].isupper())
>>> # use tuple unpacking to assign the two groups to appropriate variables
>>> upper_case, lower_case = [list(g) for (k, g) in group_by_case]
>>> upper_case
['ELEPHANT', 'LION', 'TIGER']
>>> lower_case
['cd-writer', 'keyboard', 'tv']
mylist = ['LION', 'tv', 'TIGER', 'keyboard', 'cd-writer','ELEPHANT']
[word for word in mylist if word==word.lower()]
Here is one possible solution
>>> from itertools import tee
>>>
>>> def splitOnCondition(lst, condition):
... l1, l2 = tee((condition(i), i) for i in lst)
... return [i for c, i in l1 if c], [i for c, i in l2 if not c]
...
>>> splitOnCondition(['LION', 'tv', 'TIGER', 'keyboard',
... 'cd-writer','ELEPHANT'], lambda x: x==x.lower())
(['tv', 'keyboard', 'cd-writer'], ['LION', 'TIGER', 'ELEPHANT'])

Create new list of substrings from list of strings

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'])

Categories

Resources