List comprehension and syntax mistakes with 3 arguments - python

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.

Related

For loop didn't continue [duplicate]

This question already has answers here:
Remove all occurrences of a value from a list?
(26 answers)
Closed 1 year ago.
I want to remove the select element in sequence.
For example, I want to remove all 2 in sequence [1,2,3,2,3]
my code is
def remove_all(a_list, element):
for i in range(len(a_list)):
if element == a_list[i]:
a_list.remove(element)
return a_list
The output should be [1,3,3]
but the output of my code is [1,3,2,3]
I remove the first 2 but somehow the loop didn't go further to remove second 2. I wonder where is the problem of my code
Removing items in-place will almost certainly results in index errors.
[x for x in l if x != elem]
2 things.
You are modifying a list during iteration, I linked to a good read in my comment. also here
You return in the loop thus it stops at the return. Unindent the return, python is all about indentation unlike many other popular languages in this matter.
Try instead
Building another list for return:
def remove_all(a_list, element):
result = []
for ele in a_list:
if element != ele:
result.append(ele)
return result
Using a comprehension:
def remove_all(a_list, element):
return [ele for ele in a_list if ele != element]
a possible work-around is:
while element in a_list:
a_list.remove(element)
return element
But list comprehension works too, possibly even faster.
You should place the return after the loop finishes, something like:
def remove_all(a_list, element):
for i in a_list:
if element == i:
a_list.remove(element)
return a_list
a_list = [1, 2, 3, 2, 3]
result = remove_all(a_list, 2)
print(result)
Edit:
The code above does not work with the [2,2] case as pointed out in the comments.
Another solution would be:
myList = [2,2]
myList = list(filter((2).__ne__, myList))
print(myList)
Like that you don't copy the list anywhere, just is the list you are working on avoiding a list copy that can be expensive.
The __ne__ function checks that the element exists in the list returning True or False.

Is it possible to get all element in a list in python?

Is there a function that returns the arrays that are in a list according to the search?
For example I want to get the list of tables containing the letter A
myLst = [[ABC], [BCV], [BAD]]
return [[ABC], [BAD]]
Do I have to make my own function ?
You can do in one line :
print([item for item in myLst for sub_item in item if 'A' in sub_item])
output:
[['ABC'], ['BAD']]
or as you said you want a function so here is the detailed solution :
def return_list(list_1):
result=[]
for item in list_1:
if isinstance(item,list):
for sub_item in item:
if 'A' in sub_item:
result.append(item)
return result
print(return_list(myLst))
Very possible, and simple, just do as follows
if x for x in list if 'a' in x:
#Do something
It's simple list comprehension, I recommend reading Python MDN before starting to code

Delete item from list upon a condition

I have a list of lists of tuples of integers.
ls = [[(a_1, a_2), (b_1, b_2)], [(c_1, c_2), (d_1, d_2), (e_1, e_2)], ...]
And I need to delete every item of ls that contains a tuple whose second entry is equal to a predetermined integer.
I tried this:
for item in ls:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
But for some reason, this only removes a few of the list items but not all containing a tuple with second entry = m.
Use a list comprehension:
ls = [item for item in ls if all(tuple[1] != m for tuple in item)]
Or use a filter:
ls = filter(lambda item: all(tuple[1] != m for tuple in item),ls)
Code sucks and we need less of it - here's as sparse as it gets.
[l for l in ls if m not in [i[1] for i in l]]
The best way to filter a list in python is to use a list comprehension:
filtered = [item for item in ls if not(contains_m(item))]
And then all you need is a function that can tell if an item contains m, for example:
def contains_m(item):
return any([tpl[1] == m for tpl in item])
Removing an itme from list is not a good idea while iterating though it.
Try that (if where are talking Python here)
ls = [[('a_1', 'a_2'), ('b_1', 'b_2')], [('c_1', 'c_2'), ('d_1', 'd_2'), ('e_1', 'e_2')]]
m='c_2'
print [ x for x in ls if not [ y for y in x if y[1]==m ]]
Python's list iterator is lazy. This means that when you remove an item from the list, it will skip the next item. For example, say you want to remove all ones from the following list:
[1, 1, 2]
Your for loop starts at index 0:
[1, 1, 2]
^
It removes the element and moves on:
[1, 2]
^
This example is just to help illustrate the issue. One simple workaround is to loop backwards using the index:
for ind in range(len(ls)-1, -1, -1):
item = ls[ind]
for tpl in item:
if tpl[1] == m:
del ls[ind]
break # You can end the inner loop immediately in this case
Another way is to make a copy of the list to iterate over, but remove from the original:
for item in ls[:]:
for tpl in item:
if tpl[1] == m:
ls.remove(item)
break
The last approach can be simplified into creating an output list that contains only the elements that you want. This is easiest to do with a list comprehension. See #AlexeySmirnov 's answer for the best way to do that.

Variable functions as a list but isn't technically a list? [Python]

I'm pulling a list from a dictionary like so:
d={foo:[1,2,3]}
thelist=d[foo]
I'm able to get items from indexes of thelist but not like this:
for i in thelist:
print thelist[i]
I get an error saying the "list index is out of range"
Additionally, when I run
thelist is list
it returns False
whats going on here
the list index out of range is because thelist[3] is not an allowed thing to call.
the for loop is trying to print thelist[i] for each i in thelist. In this case thelist has 1, 2, and 3. So it's trying to print thelist[1] (which is 2), thelist[2] (which is 3), and then thelist[3] which is undefined.
A bit more detail:
thelist = ['puppy', 1, 'dog']
for i in thelist:
print i
gives
puppy
1
dog
as for thelist is list, instead try type(thelist). The type of thelist is list. So testing whether thelist is list (that is it is the class of things which we call list) rather than is a list (that is it is an example of the list class) will return False.
If you want to interate over a list using indices, than you should do as follows:
for i,v in enumerate(thelist):
print(thelist[i])
Or alternatively:
for i in range(len(thelist)):
print(thelist[i])
in python the default indexing strart from 0 and ends to its lenght-1
so thelist=d[foo] ie [1,2,3] will have index 0,1,2
for i in thelist: # here i the element of list not index
print thelist[i]
for i in range(len(thelist)): # here i the index of list
print thelist[i]
for l1 in thelist:
print l1
you get:
1
2
3
in your code you're trying to access list using the list elements as index. Instead, to iterate over list' indexes, you should use range(len(theList))(from 0 to len(theList) -1) or reversed(range(len(theList)) (from len(theList) -1 to 0).
to check if a variable is a list use types
import types
x = [1,2,3]
if type(x) is types.ListType:
print 'x is a list'
Each time you go through the for loop, i is set to one of the items in the list.
You'll also want to use the type() function to compare the types of thelist and a list (really []).
d={'foo':[1,2,3]}
thelist = d['foo']
for i in thelist:
print i
print type(thelist)
print type(thelist) is type([])
returns
1
2
3
<type 'list'>
True

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