Exclude null values in map function of Python3 - python

I am using map to process a list in Python3.6:
def calc(num):
if num > 5:
return None
return num * 2
r = map(lambda num: clac(num), range(1, 10))
print(list(r))
# => [2, 4, 6, 8, 10, None, None, None, None]
The result I expect is: [2, 4, 6, 8, 10].
Of course, I can use filter to handle map result. But is there a way for map to return directly to the result I want?

map cannot directly filter out items. It outputs one item for each item of input. You can use a list comprehension to filter out None from your results.
r = [x for x in map(calc, range(1,10)) if x is not None]
(This only calls calc once on each number in the range.)
Aside: there is no need to write lambda num: calc(num). If you want a function that returns the result of calc, just use calc itself.

Not when using map itself, but you can change your map() call to:
r = [calc(num) for num in range(1, 10) if calc(num) is not None]
print(r) # no need to wrap in list() anymore
to get the result you want.

Related

How do I get the output to only be numbers within a list that are greater than x?

def list_number(mylist,x):
y=[i if i>x else False for i in mylist]
return y
I am trying to get only the numbers that are greater than x in a list to be my output and I also need it to return False if there are no numbers greater than x.
For example mylist=[1,2,3,4,5,6,7,8,9] and x=5, I want my output to be [6,7,8,9].
if x=10, I want my output to be false.
I cannot use any methods like .append or .sort
The mistake in your example is your incorrect usage of list comprehension. Here are simple examples to show you how to use list comprehension with conditional statements:
iterator = range(10)
# Example (list comprehension with if statement)
[x for x in iterator if x > 5]
# [6, 7, 8, 9]
# Example (list comprehension with if...else statement)
[x if x > 5 else 0 for x in iterator]
# [0, 0, 0, 0, 0, 0, 6, 7, 8, 9]
As for your specific question, you can use the information above to create a function like this:
def list_number(mylist, x):
y = [n for n in mylist if n > x]
if not y:
return False
return y
You can use a list comprehension and then return False if the list is empty. Using the or operator allow it to simplify it as it will execute the second statement if the first one is considered as False, so if the list is empty.
def list_number(mylist, x):
return [y for y in mylist if y > x] or False
Another way it can be done is using a filter:
def list_number(mylist, x):
return list(filter(x.__lt__, mylist)) or False
x.__lt__ correspond to the less than operator on the value of x.
Either way,
>>> list_number(list(range(10)), 5)
[6, 7, 8, 9]
>>> list_number(list(range(10)), 11)
False
You can use the fact that empty list is a false value in python.
This way your code will always return a list, which is much better than returning a List | boolean
from typing import List
def list_number(my_list: List[int], x: int) -> List[int]:
return [num for num in my_list if num > x]
result: List[int] = list_number([4,6,89,21],7)
if(result):
print('non empty result')
else:
print('empty result')
result: List[int] = list_number([4,6,89,21],790)
if(result):
print('non empty result')
else:
print('empty result')
output
non empty result
empty result
I'd say this code is pretty easy to read and predictable. No need to have any advanced knowledge. (except typehints)
from typing import List, Union
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x = 10
def greater_than(list_uf_nums: List[int], num: int) -> Union[List[int], bool]:
return_list = [y for y in list_uf_nums if y > num]
if not return_list:
return False
return return_list
print(greater_than(l, x))

How to make map for a nested function?

My intention was to mutate the list without using return. So my apporach was to create a helperfunction to modify the value and then map it to the whole list. However, map only consumes one function and one string. Thus I got stuck. Sorry for any inconvinece or misunderstanding
I have a list and two boundaries where lower boundary will replace any number below it in the list while upper boundary also replace number above it in the list.
def help(values,lower,upper):
def abc(value):
if value <= 100:
value = 100
elif value >= 0:
value = 0
else:
value
list(map (abc, values))
For example, give A=[0,1,2,3,4,5,6,7,8,9,10] with lower boundary of 2 and upper boundary of 8. It should return a list of:
[2,2,2,3,4,5,6,7,8,8,8]
The process of check will be like
A=[0,1,2,3,4,5,6,7,8,9,10]
check.expect("Function",help(A,2,8),None)
check.expect("List",help(A,2,8)[2,2,2,3,4,5,6,7,8,8,8])
Use just a list-comprehension that sets element based on conditions:
def rreplace(lst, l, u):
return [l if x < l else u if x > u else x for x in lst]
A = [0,1,2,3,4,5,6,7,8,9,10]
print(rreplace(A, 2, 8))
# [2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8]

Python difference between filter() and map()

Being new to python I am just trying to figure out the difference between filter() and map().
I wrote a sample script as follows:
def f(x): return x % 2 == 0
def m(y): return y * 2
list = [1,2,3,4]
flist = filter(f, list)
print(list)
print(flist)
mlist = map(m, list)
print(list)
print(mlist)
We see that to both the filter and map we pass a list and assign their output to a new list.
Output of this script is
[1, 2, 3, 4]
[2, 4]
[1, 2, 3, 4]
[2, 4, 6, 8]
Question arises is that function call of both filter and map looks same so how will they behave if we interchange the contents of functions passed to them.
def f(x): return x * 2
def m(y): return y % 2 == 0
list = [1,2,3,4]
flist = filter(f, list)
print(list)
print(flist)
mlist = map(m, list)
print(list)
print(mlist)
This results in
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[False, True, False, True]
This shows filter evaluates the function and if true it returns back the passed element.
Here the function
def f(x): return x * 2
evaluates to
def f(x): return x * 2 != 0
In contrast map evaluates the function expression and returns back the result as items.
So filter always expects its function to do comparison type of task to filter out the elements while map expects its functions to evaluate a statement to get some result.
Is this understanding correct?
They both work a little bit differently but you've got the right idea.
Map takes all objects in a list and allows you to apply a function to it
Filter takes all objects in a list and runs that through a function to create a new list with all objects that return True in that function.
Here's an example
def square(num):
return num * num
nums = [1, 2, 3, 4, 5]
mapped = map(square, nums)
print(*nums)
print(*mapped)
The output of this is
1 2 3 4 5
1 4 9 16 25
Here's an example of filter
def is_even(num):
return num % 2 == 0
nums = [2, 4, 6, 7, 8]
filtered = filter(is_even, nums)
print(*nums)
print(*filtered)
The output of this would be
2 4 6 7 8
2 4 6 8
In map: Function will be applied to all objects of iterable.
In filter: Function will be applied to only those objects of iterable who goes True on the condition specified in expression.
As per my understanding below are the difference between map and filter:
def even(num):
if(num % 2 == 0):
return 'Even'
num_list = [1,2,3,4,5]
print(list(filter(even,num_list))) ->>>>>>>output: [2, 4]
print(list(map(even,num_list))) ->>>>>>> output: [None, 'Even', None, 'Even', None]
So, we can say that:
filter(): formats new list that contains elements which satisfy specific condition.
map(): function iterates through a all items in the given iterable and executes a function which we passed as an argument.
I think yes you got the picture pretty much.
both Map and filter are ways of applying function to iterables.
in Map you can use multiple iterables
definition : map(function_object, iterable1, iterable2,...)
whereas
in filter only one iterable can be used
definition : filter(function_object, iterable)
further in filter the function_object has to return boolean only.
for sake of example following is the Map with multiple iterables as input
list_a = [1, 2, 3]
list_b = [10, 20, 30]
map(lambda x, y: x + y, list_a, list_b) # Output: [11, 22, 33]
The filter() and map() functions are a little bit different.
While Maps takes a normal function, Filter takes Boolean functions. As a matter of fact, filter are maps with conditional logic, a Boolean logic.
Your example is too accurate.
In filter function your supposed to pass a function and a list(the function must evaluate to true or false). If the element passed in the function returns true the filter function will put the element passed into a new list. Where as map function will take an element pass it through a function and return the output of the function and store that to the new list.
map(): Function will be applied to all objects of iterable, we can use as many literables as wee needed
filter(): Function will be applied to only those objects of iterable and added to result which item is True, we can use only one literable
In the below, code 0 is not add in the filter function because 0 is a representation for False in some cases so it is not added to the filter and added in the map function result
def check(num):
return num*1
nums = [0,2, 4, 6, 7, 8]
result = filter(check, nums)
print(list(result))
def check(num):
return num*1
nums = [0,2, 4, 6, 7, 8]
result = map(check, nums)
print(list(result))
map() applies any applicable logic presented to any number of arguments of type list and returns an iterable containing values mapped to each respective members of the argument list(s).
example:
m = map(lambda x,y: 10+x+y, [1,2,3,4],[10,20,30,40])
print(list(m))
output:
[21, 32, 43, 54]
filter() applies the condition specified to one argument of type list and returns an iterable containing values that satisfy the specified condition and thus selected from the argument.
example:
f = filter(lambda x: x<3, [1,2,3,4])
print(list(f))
output:
[1, 2]
The main difference between a map and a filter is the return of values. A map will always have a representation for elements in the list. The filter will filter out the only elements that will meet the conditions in the function.
def checkElementIn(a):
nameList = ['b','a','l','l']
if a in nameList:
return a
testList = ['r','e','d','b','a','l','l']
m_list = map(checkElementIn,testList)
for i in m_list:
print(i)
None
None
None
b
a
l
l
f_list = filter(checkElementIn,testList)
for i in f_list:
print(i)
b
a
l
l
Those are completely different
just take a look at this clear example down below:
def sqr(x):
return x%2==0
mp = map(sqr, [-1,0,1,2,3,4,5,6])
print(list(mp))
[False, True, False, True, False, True, False, True]
fl = filter(sqr, [-1,0,1,2,3,4,5,6])
print(list(fl))
[0, 2, 4, 6]
as you can see in this clear example the filter doesn't care about the function results! It just checks which one of the list items would be true belonging to the calculation def, and the return is a list [0, 2, 4, 6] which means we have got a true result of numbers

Run a function returning a set on a set, and get back a larger set

We can use list comprehensions on a list, and get back a list of each element run through a function. We can do the same thing with a set.
I'm looking to run each element of a set through a function, that could return another set, larger than the original input. Is this possible with comprehensions?
I could do something like this, but is there a one-liner for it?
ret = set()
q = { 1, 2, 3, 4 }
def doubleIt( t ):
return { t, t**2 }
for w in q:
ret.update( doubleIt( w ) )
ret
>> { 1, 2, 3, 4, 9, 16 }
The returning function will be much more complex, and could possibly return a set of sets, which I'll have to reduce further, so a one-liner would be very useful.
EDIT: Note that the returning function might also return a set. See in the example that running 2 through the function returns {2, 4} and running 4 through it returns {4, 16}, yet 4 only appears in the desired output once.
Two expressions yet, it's a one-liner which is not long:
q = { 1, 2, 3, 4 } # given
def f(x):
return x * x
ret = q | set(f(x) for x in q)
In case f(x) returns a set:
reduce(lambda a, b: a | b, map(lambda a: f(a), q))
Using set.union + reduce + map
In [27]: reduce(set.union,map(doubleIt,q))
Out[27]: {1, 2, 3, 4, 9, 16}
Just apply map function will apply the function into all elements and that will return a list of set. Then combine the set.
Here's a short way to do it without comprehensions:
set().union(*map(doubleIt, q))
It calls doubleIt on every element of q and merges the resulting sets into one set with set().union.
If you want a comprehension, use a set comprehension with two for clauses:
ret = {new_elem for elem in q for new_elem in doubleIt(elem)}
This iterates over q, calls doubleIt on each element, and iterates over the sets returned by doubleIt, putting the elements of those sets in the new set. It's equivalent to
ret = set()
for elem in q:
for new_elem in doubleIt(elem):
ret.add(new_elem)
One liner solution:
z=set(map(lambda x:x**2,q)).union(q)
The best one-liner, IMO is this:
q = { 1, 2, 3, 4 }
l = set(elem **2 for elem in q).union(q)

Duplicate number in List remove in python

I just want simple list which remove duplicate digit
a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
m = []
def single_digit_list(a):
return [m.append(x) for x in a if x not in m]
print "New List", single_digit_list(a)
I was expected that new list gave me the one digit in list not repeated but i got following output
New List [None, None, None, None, None, None, None, None, None]
I can't understand what going on
Simple Know what is wrong in code
use set to remove duplicates:
m=set(a)
If you wanted output to be list:
m=list(set(a) )
Your code is good..You just have to return m...instead of returning return value of append...For ex, print m.append(10) will print None which is actually append's return value,you are not printing m.
You could modify you code as follows to return list:
a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
def single_digit_list(a):
m = []
[m.append(x) for x in a if x not in m]
return m #you have appended elements to m
You are trying to return a list of lists where all the lists are None.
This is because m.append() does not return anything and you are trying to create a list of what m.append returns
Just do it as:
def single_digit_list(a):
m = []
for x in a:
if x not in m:
m.append(x)
return m
>>> print single_digit_list([2,3,4,4,4,4,5,6,7,8,9,9,9,9,0])
[2,3,4,5,6,7,8,9,0]
If your list is already grouped, you can use groupby.
>>> x = [1, 1, 4, 4, 4, 5, 2, 2, 2, 3, 3]
>>> from itertools import groupby
>>> print [i[0] for i in groupby(x)]
[1, 4, 5, 2, 3]
This solution does not break order of element instead of converting to set.
The reason why you got list of None value is :
List comprehension is use to generate a list base on the return of the expression given inside the list comprehension.
Eg: [ expression for item in list if conditional ]
So, in your case you are appending an item into a list, which return None after appending the item if it was appending successfully.
Eg:
>>> ls = []
>>> print ls.append('a')
None
>>>
So, at the end of your list comprehension, your list m got the correct unique element list but you return the list generate by the comprehension which is a list of None value.
Conclusion:
You can fix that by return the value of m not the result of list comprehension.
Or here is another easy solution using dictionary key:
>>> a = [2,3,4,4,4,4,5,6,7,8,9,9,9,9,0]
>>> dict.fromkeys(a).keys()
[0, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

Categories

Resources