making a string into a list within a list comprehension - python

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]

Related

function that counts unique characters for even-lengthed strings in a list? (List Comprehension)

I want to make a function that first filters through a list and retrieves values of even length. Then, it counts the unique characters in each evenly-lengthed value then returns the amount as a list of numbers. The function is not case-sensitive, so it counts lower and upper case characters as the same. To specify, however, I would like to write this function using list comprehension without using lambda or imports. I would also like to write it without using for-loops outside of the list comprehension.
for example unique_evens([‘tifa’, ‘cloud’, ‘barret’]) should return [4, 5]. This is because the function only counts the unique characters in ‘tifa’ and ‘barret’ and skips over ‘cloud’ because the word is 5 characters long.
What I've tried:
def unique_even(names):
even_numbered_names = []
numbers = []
for i in range(len(names)):
if len(names[i])%2 == 0:
even_numbered_names.append(names[i])
for i in range(len(even_numbered_names)):
numbers.append(len(set(even_numbered_names[i])))
return numbers
when unique_even(['Cloud','Tifa','Barret']) is inputted into the function, it returns [4,5]. So the function works as intended. However, I would like to know how I could shorten this function using list comprehension. If possible, can this function be defined and returned in a single line?
You can achieve filtering in list comprehension:
def unique_evens(lst):
return [len(set(word.lower())) for word in lst if len(word) % 2 == 0]
print(unique_evens(['tifa', 'cloud', 'barret'])) # [4, 5]

Check if each string (all of them) on a list is a substring in at least one of the strings in another

I am having a hard time trying to check if all of the strings in a python list are a subset of any string in another Python list.
Example:
I want to check if each string(all of them) of list1 is in at least one of the strings in the list2 and if it is, do something.
list1 = ['tomato', 'onions','egg']
list2 = ['Two tomatos', 'two onions','two eggs','salsa']
In this example for instance it would return True.
You can use generator expressions combined with any/all functions:
>>> list1 = ['tomato', 'onions','egg']
>>> list2 = ['Two tomatos', 'two onions','two eggs','salsa']
>>> all(any(i in j for j in list2) for i in list1)
True
You can do with a single command using list comprehension, any, and all.
list1 = ['tomato', 'onions','egg']
list2 = ['Two tomatos', 'two onions','two eggs','salsa']
result = all([any([keyword in string for string in list2]) for keyword in list1])
The first list comprehension [keyword in string for string in list2]checks that a keyword is at least present in all strings of list2 and produces a list of boolean. We use any to determine if any result was True.
The second list comprehension is built on top of the first list comprehension [any([keyword in string for string in list2]) for keyword in list1] and checks that all keywords were are least present in all the string of list2. We use all to check that all results are True.
As #Selcuk mentioned, you can do it more efficiently using generator expressions: the syntax is really is really close to list comprehensions:
result = all(any(keyword in string for string in list2) for keyword in list1)
You could go through the lists and execute something if it meets the condition that the word from list 1 exists in some element of list 2, for example:
list1 = ['tomato', 'onions','egg']
list2 = ['Two tomatos', 'two onions','two eggs','salsa']
for i in list1:
for j in list2:
if i in j:
print("something to ", i, " and ", j)

List comprehension and syntax mistakes with 3 arguments

Here is the question:
Implement function processList2(inputList, specialItem, ignoreItems) that returns a new list that contains all the items of inputList (and in the original order) except
Remove any that appear in the list ignoreItems
Occurrences of specialItem (if specialItem is not in ignoreItems) should become the string "special" in the new list.
I am trying to create a new list from inputList using list comprehension. I can get items not in ignoreItems, but can't seem to figure out how to print 'special' if item == specialItem.
Here's what I have so far:
def processList2(inputList, specialItem, ignoreItems):
return [item for item in inputList if item not in ignoreItems]
a sample output is something like:
>>> processList2([1,1,2,2], 1, [2])
['special', 'special']
or
>>> processList2([1,2,3,4,True,'dog'], 4, [3,5,4])
[1, 2, True, 'dog']
You can use the ternary operator in Python.
def processList2(inputList, specialItem, ignoreItems):
return [item if item != specialItem else "special" for item in inputList if item not in ignoreItems]
See also this post for more on the subject.

Why my reverse() method doesn't work in python 3?

I was trying to do this exercise where you have to take a word and check if it's a palindrome. I tried to do it with making a string in to a list then reversing it and turning it back to a string, but the reverse method doesn't work for me for some reason, I checked and the usage is correct.
word = input('Give me a word:\n')
b = []
wordLetters = word.split()
b = wordLetters.reverse()
word2 = ''.join(b)
if word == word2:
print('Yay')
else:
print('heck')
it just shows
TypeError: can only join an iterable
In Python reverse method of list does the operation in-place e.g. it modifies the list you apply this operation to. This method has no return value.
l = [1, 2, 3, 4]
l.reverse()
print(l)
Output:
[4, 3, 2, 1]
If you try to get value returned by reverse you will get None:
print([1, 2, 3, 4].reverse())
Output:
None
If you need a reversed copy of your list you should use reversed function:
l = [1, 2, 3, 4]
r = reversed(l)
print(r)
print(list(r))
Output:
<list_reverseiterator object at 0x7ff37e288ef0>
[4, 3, 2, 1]
Notice that it returns iterator, not the list itself. You can pass that iterator to join function or you can build a list from it using list constructor.
The same is true for method sort and function sorted.
reverse() method of list doesn't return anything but reverses the list itself in Python 3. So join wordLetters not b.Hope this solves the issue.
As the documentation states:
list.reverse()
Reverse the elements of the list in place.
That means this method won't return anything (otherwise it would state what it returns) and that it reverses the list in-place.
Also str.split will (by default) split at whitespaces which is probably not intended from the problem description.
My suggestion would be to simply use slice notation for reversing the string:
word = input('Enter your word')
if word == word[::-1]:
print('Yay')
else:
print('heck')

While loop with single quotes for a condition in Python

I came across the following line of code in Python and I keep wondering what does it do exactly:
while '' in myList:
myList.remove('')
Thanks in advance.
It removes all empty strings from a list, inefficiently.
'' in myList tests if '' is a member of myList; it'll loop over myList to scan for the value. myList.remove('') scans through myList to find the first element in the list that is equal to '' and remove it from the list:
>>> myList ['', 'not empty']
>>> '' in myList
True
>>> myList.remove('')
>>> myList
['not empty']
>>> '' in myList
False
So, the code repeatedly scans myList for empty strings, and each time one is found, another scan is performed to remove that one empty string.
myList = [v for v in myList if v != '']
would be a different, more efficient way of accomplishing the same task. This uses a list comprehension; loop over all values in myList and build a new list object from those values, provided they are not equal to the empty string.
Put simply, it removes all empty strings from myList.
Below is a breakdown:
# While there are empty strings in `myList`...
while '' in myList:
# ...call `myList.remove` with an empty string as its argument.
# This will remove the one that is currently the closest to the start of the list.
myList.remove('')
Note however that you can do this a lot better (more efficiently) with a list comprehension:
myList = [x for x in myList if x != '']
or, if myList is purely a list of strings:
# Empty strings evaluate to `False` in Python
myList = [x for x in myList if x]
If myList is a list of strings and you are on Python 2.x, you can use filter, which is even shorter:
myList = filter(None, myList)
In Python, two single quotes '' or double quotes "" represent the empty string.
The condition to keep looping is while the empty string exists in the list, and will only terminate when there are no more empty strings.
Therefore, it removes all empty strings from a list.

Categories