Sort the letters in each string alphabetically Python function - python

I want to write a function that takes a list of strings, sort the letters in each string, and then sort the full list.
So I created a list of strings "a". This code works perfectly, but is there any way to split the code for b variable? I want this function to sort the letters in each string first and then sort the full list.
a = ['hi' , 'hello', 'at', 'this', 'there', 'from']
def string_fun(a):
for i in a:
b= sorted(''.join(sorted(i)) for i in a)
return(b)
string_fun(a)
I was trying this:
a = ['hi' , 'hello', 'at', 'this', 'there', 'from']
def string_fun(a):
for i in a:
b=''.join(sorted(i))
for i in b:
c= sorted()
return(c)
string_fun(a)
But I get an error "sorted expected 1 argument, got 0"

You are misunderstanding the syntax for for-loops in python. When you write for x in a, variable x is not an index to be used to get an element as a[x]. Variable x is the element.
So you can write:
result = []
for x in a:
result.append(''.join(sorted(x)))
result.sort()
Or equivalently:
result = []
for i in range(len(a)):
result.append(''.join(sorted(a[i])))
result.sort()
Or equivalently, use a list comprehension:
result = sorted(''.join(sorted(x)) for x in a)
Please take some time to read more about loops and list comprehensions in python:
loops in python;
list comprehensions.

Related

How do I shorten this code with python list comprehension?

I am trying to code this,
def retrieve_smallest_letter(words):
"""
Input: 'words' (lst) which represents a list of strings.
Output: A new list with the smaller letter of the each word's
first and last index value compared to be appended to the list.
For Example:
>>> lst = ['sandbox', 'portabello', 'lion', 'australia', 'salamander']
>>> retrieve_smallest_letter(lst)
['s', 'o', 'l', 'a', 'r']
"""
My code
def retrieve_smallest_letter(words):
lst = []
for i in range(len(words)):
first_word = words[i][0]
last_word = words[i][len(words[i])-1]
if first_word < last_word:
lst.append(str(first_word))
else:
lst.append(str(last_word))
return lst
How can I shorten this code with list comprehension?
First thing to understand is that a list comprehension is fundamentally restricted semantics on a for loop:
r = [a for a in b if c]
is essentially syntactic sugar for
r = []
for a in b:
if c:
r.append(a)
so the first step is to get the problem into a "shape" which fits a list comprehension:
simple iteration and filtering
no assignments (because that's as yet not supported)
only one production
Using Python correctly also help, do let's start by simplifying the existing loop:
iterate collections directly, Python has a powerful iterator protocol and you don't usually iterate by indexing unless absolutely necessary
use indexing or destructuring on the word, Python allows indexing from the end (using negative indices)
perform the selection "inline" as a single expression, using either a conditional expression or in this case the min builtin which does exactly what's needed
def retrieve_smallest_letter(words):
lst = []
for word in words:
lst.append(min(word[0], word[-1]))
return lst
or
def retrieve_smallest_letter(words):
lst = []
for first, *_, last in words:
lst.append(min(first, last))
return lst
from there, the conversion is trivial (there is no filtering so it can be ignored):
def retrieve_smallest_letter(words):
return [min(first, last) for first, *_, last in words]
Yes
[min(word[0], word[-1]) for word in words]
lst = [min(w[0], w[-1]) for w in words]

Difference between map and filter in python

I have the following code(which uses map) to check whether any string in mylist is present in any string in list1 and if it is, the code prints the string from list1. This code is working perfectly fine.
mylist=['dog','cat','bil']
def check(string1):
list1=['doggy','abc','def','catelyn','billy']
for i in list1:
if(string1 in i):
return i
x=list(map(check,mylist))
x
Now if I keep the code same, and replace map with filter, it prints the substrings(from mylist)
mylist=['dog','cat','bil']
def check(string1):
list1=['doghdjd','asnkbakv','bsvbubdb','gfdtcatkbnk','bkkbill']
for i in list1:
if(string1 in i):
return i
x=list(map(check,mylist))
x
I am still returning the string from list1 but the other strings are added to x. Why is this happening?
map apply the function to each element, so it replaces the value in the array by the result of the function, it's like
[check(value) for value in mylist]
filter applies the function as a test, to know if it keeps the value or not, here as the function always return a string (for the given input) it's evaluated as non-false so it keeps all
[value for value in mylist if check(value)]
If you use list1 = ['doggy', 'abc', 'def', 'catelyn', 'b-illy'], check('bil') will return None, so the filter will not keep bil :
print(list(map(check, mylist))) # ['doggy', 'catelyn', None]
print(list(filter(check, mylist))) # ['dog', 'cat']

How to XOR two lists in Python? [duplicate]

This question already has answers here:
Comparing two lists and only printing the differences? (XORing two lists)
(6 answers)
Closed 2 years ago.
I've got two lists, for example:
a = ['hello','world']
b = ['hello','world','im','steve']
If I want to create a third list that only contains elements NOT in both:
c = ['im','steve']
How do I do this if the order of the elements IS important? I know I can use sets but they keep throwing out the order of my lists. I could use ' '.join(list) to convert them to strings but not sure how to do this operation in that format either.
You can concatenate the lists and use list comprehension:
a = ['hello','world']
b = ['hello','world','im','steve']
final_vals = [i for i in a+b if i not in a or i not in b]
Output:
['im', 'steve']
Option 1: set method (recommended)
Sets have a symmetric_difference method that exclusively return elements from either a or b. Order can be preserved with a list comprehension for a concatenated list a + b.
comp = set(a).symmetric_difference(b)
[x for x in a + b if x in comp]
# ['im', 'steve']
Option 2: pathlib method
For reference, another way to diff two lists might be with pathlib.Path.relative_to method:
import pathlib
p = pathlib.Path(*b)
r = p.relative_to(*a)
list(r.parts)
# ['im', 'steve']
Note: b is the longer list. This option is potentially less efficient than a simple list comprehension.
Add two lists together and minus the intersection part if it shows in the new list. Order is preserved.
c = a + b
for v in set(a).intersection(set(b)):
while v in c:
c.remove(v)
a = ['hello','world']
b = ['hello','world','im','steve']
a = set(a)
b = set(b)
print(a.symmetric_difference(b))
This code print elements that are only in one of the tables.
Look here:
https://learnpython.org/en/Sets
You could also just create a function that filters elements from l1 that don't exist in l2, and call it twice with the arguments flipped:
a = ['hello','world', 'foo']
b = ['hello','world','im','steve']
def difference(l1, l2):
return list(filter(lambda x: x not in l2, l1))
print(difference(a, b) + difference(b, a))
# ['foo', 'im', 'steve']
If you don't wish to use filter(), a simple list comprehension like this also works:
[item for item in l1 if item not in l2]
The question is not very clear, indeed, and probably you're good with #Ajax1234 's answer, but here's another "take" on it.
If you wanna compare positions (kind of what a bit-wise XOR would do) you can do something like getting the shortest list, iterate checking position by position with the longest list (check the same position in the longest list matches the word in the shortest list) and then add the remainder (the "unwalked" part of the longest list). Something like the following:
a = ['hello', 'world']
b = ['hello', 'world', 'im', 'steve']
min_list = a if len(a) < len(b) else b
max_list = b if len(b) > len(a) else a
results = []
for i, item in enumerate(min_list):
# Iterate through the shortest list to avoid IndexError(s)
if min_list[i] != max_list[i]:
results.append(min_list[i])
results.append(max_list[i])
results.extend(max_list[i + 1:])
print(results)
# Prints: ['im', 'steve']
However, then you have the problem of what to do if the same positions don't match. I mean... What to do in that case? In the code above, I just added both entries to the results list, which means for the following inputs:
a = ['hello', 'foo']
b = ['hello', 'world', 'im', 'steve']
would output:
>>> ['foo', 'world', 'im', 'steve']
(notice both foo from list a and world from list b have been added)
Using standard for loop to check for items not in one or the other list (may be more understandable than list comprehension):
a = ['hello','world', 'foo']
b = ['hello','world','im','steve']
c = a+b
ans = []
for i in c:
if i not in a or i not in b:
ans.append(i)
print(ans)
Output:
['foo', 'im', 'steve']
I recommend, using ^ operator with sets, like set(a) ^ set(b), Example (demo):
>>> a = ['hello','world']
>>> b = ['hello','world','im','steve']
>>> set(a) ^ set(b)
{'steve', 'im'}
>>> sorted(set(a) ^ set(b),key=max([a,b],key=len).index)
['im', 'steve']
>>>
https://docs.python.org/2/library/stdtypes.html#frozenset.symmetric_difference

Python convertion of list of strings to list of tuples

How to convert following list
['abc,cde,eg,ba', 'abc,cde,ba']
in to list of tuples?
[('abc','cde','eg','ba'), ('abc','cde','ba')]
What I have tried
output = []
for item in my_list:
a = "','".join((item.split(',')))
output.append(a)
In your loop, you are splitting the string (which will give you a list), but then you are joining it back with a ,, which is returning to you the same string:
>>> 'a,b'.split(',')
['a', 'b']
>>> ','.join('a,b'.split(','))
'a,b'
You can convert a list to a tuple by passing it to the the built-in tuple() method.
Combining the above with a list comprehension (which is an expression that evaluates to a list), gives you what you need:
>>> [tuple(i.split(',')) for i in ['abc,cde,eg,ba', 'abc,cde,ba']]
[('abc', 'cde', 'eg', 'ba'), ('abc', 'cde', 'ba')]
The longhand way of writing that is:
result = []
for i in ['abc,cde,eg,ba', 'abc,cde,ba']:
result.append(tuple(i.split(',')))
print(result)
t=['abc,cde,eg,ba', 'abc,cde,ba']
for i in t:
print tuple(i.split(','))
you can split the 2 elements. Here is my code
['abc,cde,eg,ba', 'abc,cde,ba']
a='abc,cde,eg,ba'
b='abc,cde,ba'
c=[]
c.append(tuple(a.split(',')))
c.append(tuple(b.split(',')))
print c

What Expression Behind Python For In Loop Does

In this example:
sorted_data = [files.data[ind] for ind in sort_inds]
May someone please provide an explanation as to how the expression behind the for loop is related or how it is working, thanks.
It's called a List Comprehension
In other words
sorted_data = [files.data[ind] for ind in sort_inds]
is equivalent to:
sorted_data = []
for ind in sort_inds:
sorted_data.append(files.data[ind])
It's just a lot more readable using the comprehension
ok so here is a simple example:
say i have a list of ints:
nums = [1,2,3]
and i do this:
[i**2 for i in nums]
it will output:
[1, 4, 9]
this is equivalent to this:
for i in nums:
list.append(i**2)
because it iterated through the list and squared each item in the list
another example:
say i have a list of strings like this:
list1 = ['hey, jim','hey, pam', 'hey dwight']
and I do this:
[phrase.split(',') for phrase in list1]
this will output this list:
[['hey', ' jim'], ['hey', ' pam'], ['hey dwight']]
this is equivalent too:
for phrase in list1:
new_phrase = phrase.split(',')
list.append(new_phrase)
it went through and made a list out of each item but it used split on each item
its basically a compacted for loop and instead of using append() it just creates the list!. it is much more readable and takes less lines
learn more here
It means for every item in this case ind present in sort_inds, pass it as a parameter to the function files.data[ind].
Save the result in a list (sorted_data)

Categories

Resources