python- reverse 2 strings in 1 list separately? - python

In python, I have this list containing
['HELLO', 'WORLD']
how do I turn that list into
['OLLEH', 'DLROW']

>>> words = ['HELLO', 'WORLD']
>>> [word[::-1] for word in words]
['OLLEH', 'DLROW']

Using a list comprehension:
reversed_list = [x[::-1] for x in old_list]

Arguably using the builtin reversed is more clear than slice notation x[::-1].
[reversed(word) for word in words]
or
map(reversed, words)
Map is fast without the lambda.
I just wish it was easier to get the string out of the resulting iterator. Is there anything better than ''.join() to put together the string from the iterator?

Using map and lambda(lambdas are slow):
>>> lis=['HELLO', 'WORLD']
>>> map(lambda x:x[::-1],lis)
['OLLEH', 'DLROW']

Related

How can I extract words before some string?

I have several strings like this:
mylist = ['pearsapple','grapevinesapple','sinkandapple'...]
I want to parse the parts before apple and then append to a new list:
new = ['pears','grapevines','sinkand']
Is there a way other than finding starting points of 'apple' in each string and then appending before the starting point?
By using slicing in combination with the index method of strings.
>>> [x[:x.index('apple')] for x in mylist]
['pears', 'grapevines', 'sinkand']
You could also use a regular expression
>>> import re
>>> [re.match('(.*?)apple', x).group(1) for x in mylist]
['pears', 'grapevines', 'sinkand']
I don't see why though.
I hope the word apple will be fix (fixed length word), then we can use:
second_list = [item[:-5] for item in mylist]
If some elements in the list don't contain 'apple' at the end of the string, this regex leaves the string untouched:
>>> import re
>>> mylist = ['pearsapple','grapevinesapple','sinkandapple', 'test', 'grappled']
>>> [re.sub('apple$', '', word) for word in mylist]
['pears', 'grapevines', 'sinkand', 'test', 'grappled']
By also using string split and list comprehension
new = [x.split('apple')[0] for x in mylist]
['pears', 'grapevines', 'sinkand']
One way to do it would be to iterate through every string in the list and then use the split() string function.
for word in mylist:
word = word.split("apple")[0]

Sort list of strings alphabetically

So i have a question, how can i sort this list:
['Pera','mela','arancia','UVA']
to be like this:
['arancia','mela','Pera','UVA']
In the exercise it said to use the sorted() function with the cmp argument.
You can easily do that, using the key argument:
my_list = ['Pera','mela','arancia','UVA']
my_list.sort(key=str.lower)
Which will get your lowercases chars first.
This will change the object in-place and my_list will be sorted.
You can use sorted function with the same key argument as well, if you want to have a new list. For example:
my_list = ['Pera','mela','arancia','UVA']
my_sorted_list = sorted(my_list,key=str.lower)
Output will be:
>>> my_list
['Pera','mela','arancia','UVA']
>>> my_sorted_list
['arancia', 'mela', 'Pera', 'UVA']
You need to sort your elements based lowercase representation of the strings:
sorted(['Pera','mela','arancia','UVA'], key=str.lower)
this will output:
['arancia', 'mela', 'Pera', 'UVA']
Use sorted() with a key.
>>> mc = ['Pera','mela','arancia','UVA']
>>> sorted(mc, key=str.lower)
['arancia', 'mela', 'Pera', 'UVA']
This will help you:
>>> words = ['Pera','mela','arancia','UVA']
>>> sorted(words)
['Pera', 'UVA', 'arancia', 'mela']
>>> sorted(words, key=str.swapcase)
['arancia', 'mela', 'Pera', 'UVA']
Hope this helps

Comparing elements in two lists when keeping duplicates is desired in Python

I'd like to compare two lists. I'd like to find elements in the first list that don't have a corresponding entry in the second list (order doesn't matter):
a = ['hi', 'hi', 'bye', 'hi']
b = ['hi', 'hi', 'bye']
So I would like the output to be
c = ['hi']
since the first list has an extra 'hi' in it that doesn't appear in the second list.
If I do one of the usual techniques, I can use a list comprehension:
[x for x in a if x not in b]
which gives me [], which is not what I want.
Things I've tried involve using the set operator, which have the same outcome, since that operation reduces the members of the list to uniqueness.
This seems like a simple operation. Do I need to enumerate each element in the lists first, and create tuples to compare? Do I need to put them into a Counter dict? All this sounds a little bit like overkill when I just want to a simple comparison of the elements in a list!
Counter objects support multi-set operations:
>>> from collections import Counter
>>> a = ['hi', 'hi', 'bye', 'hi']
>>> b = ['hi', 'hi', 'bye']
>>> Counter(a) - Counter(b)
Counter({'hi': 1})
Rebuilding a list from the Counter:
>>> list(counter.elements())
['hi']
You can do it simply without requiring any imports, with a while loop, checking each item:
a = ['hi', 'hi', 'bye', 'hi']
b = ['hi', 'hi', 'bye']
c = []
while a:
# Get first item (and remove).
item = a.pop(0)
if item in b:
b.remove(item)
else:
c.append(item)
print c

Replacing "<" with "*" with a Python regex

I need to go through strings in a list "listb", replacing the character "<" with "*".
I tried like this:
import re
for i in listb:
i = re.sub('\<','\*', 0)
But I keep getting TypeError: expected string or buffer.
Not sure what am I doing wrong and examples on the net were not much help.
See the docs
As per Seth's comment, the best way to do this using regular expressions is going to be:
listb = [re.sub(r'<',r'*', i) for i in listb]
As #Paco, said, you should be using str.replace() instead. But if you still want to use re:
You're putting 0 where the string is supposed to go! The TypeError is from the that third parameter. It's an int, needs to be a string.
Side note: always use raw strings, denoted by r'', in your regexes, so you don't have to escape.
>>> listb = ['abc', '<asd*', '<<>>**']
>>> for i in listb:
... i = re.sub(r'<',r'*', i)
... print i
...
abc
*asd*
**>>**
>>> listb
['abc', '<asd*', '<<>>**']
if you want a new list with all those replaced, do:
>>> listx = []
>>> for i in listb:
... listx.append(re.sub(r'<',r'*', i))
...
>>> listx
['abc', '*asd*', '**>>**']
>>> listb
['abc', '<asd*', '<<>>**']
>>> listb = listx
If you really don't want to create a new list, you can iterate through the indices.
Note that you're not changing i in the list. I would create a new list here. Each i here is its own variable, which doesn't point to listb.
>>> my_string = 'fowiejf<woiefjweF<woeiufjweofj'
>>> my_string.replace('<', '*')
'fowiejf*woiefjweF*woeiufjweofj'
Why are you using the re module for such a simple thing? you can use the .replace method.

making a string into a list within a list comprehension

What is asked:
By filtering the lowers list, create a list of the words which are at least 5 letters long and which have their letters already in alphabetical order.
What I have:
[word for word in lowers if len(word)>= 5 and word.sort=word]
I know that this will not work because the word.sort is being used on a string and word needs to be a list to make this function work. How would I do this in side the list comprehension or do i need to define something before.
>>> sorted('foo') == list('foo')
True
>>> sorted('bar') == list('bar')
False
The easiest way is to use list comprehension:
[word for word in lowers if len(word)>=5 and sorted(word)==list(word)]
Another is to use Python 2's filter function for stuff like this. Also, this uses string.join to convert sorted list back to string
#Lambda function to test condition
test = lambda x: len(x)>=5 and ''.join(sorted(x))==x
#Returns list of elements for which test is True
filter(test, lowers)
Plain ol' function (bonus: generators and yield!):
def filterwords(lst):
for word in lst:
if len(word)>=5 and sorted(word)==list(word):
yield word
The last one is most efficient, resource-wise and such.
Update: .sort() can be used on lists (not strings) to sort a list directly, but it does not return a value. So, list(word).sort() is of no use here; we use sorted(word).
>>> lst = [1,100,10]
>>> sorted(lst) #returns sorted list
[1, 10, 100]
>>> lst #is still the same
[1, 100, 10]
>>> lst.sort() #returns nothing
>>> lst #has updated
[1, 10, 100]

Categories