Accessing a list with only recursion and lambdas - python

As part of my homework I have to access every element o a list without a for loop to use it in a function I'm allowed to use, e.g:
myList=['Hello','World']
I've tried using lambda functions (Because I'm not allowed to declare functions with Def) but didn't work.
function(next(myList))
Also tried using next(myList) but sometimes the list can have 1000+ elements.

Use lambda with map for apply a function to each element:
myList=['Hello','World']
list(map(lambda x: x.upper(), myList))

Using map is the shortest way to do it. You don't need lambda.
li = list(range(10)) # this is your list
list(map(print, li)) # view each element

If you can use function you can use that trick
You can use recursion to access all elements.
At first create a function to read first element and delete that element.
Use that function again and again until the list is empty.
def show(my_list):
try:
print(my_list[0])
del my_list[0]
show(my_list)
except:
pass
Or if you want to do some action
new = []
def action(my_list):
try:
x = do_something(my_list[0])
del my_list[0]
new.append(x)
action(my_list)
except:
pass
Here do_something(data) is your custom function.

I believe the cleanest way to do this is with a map function:
l = [1,2,3]
list(map(lambda x : print(x), l))
# returns
# >> 1
# >> 2
# >> 3

Related

How to pass arguments to a function in "map" function call?

I know a map function gets a function as its first argument and the next arguments are iterators on which the passed function needs to be applied. My question here is say if I have a 2d list like so
l=[[1,2,3],[4,5,6],[7,8,9]]
how can I sort the individual lists in reverse order so my output is
l=[[3,2,1],[6,5,4],[9,8,7]]
I know a potential solution is using a lambda function such as
list(map(lambda x:x[::-1],l))
I want something like this
list(map(sorted, l,'reversed=True'))
where 'reversed=True' is an argument that sorted takes
eg:
>>> newList=[1,2,3]
>>> sorted(newList,reversed='True')
>>> [3,2,1]
I have seen how to pass arguments to a the pow function using the itertools.repeat module
map(pow,list,itertools.repeat(x))
x=power to which the list must be raised
I want to know if there is any way the arguments can be passed in a map function. In my case the 'reverse=True' for the sorted function.
You can use functools.partial for this:
import functools
new_list = list(map(functools.partial(sorted, reverse=True), l))
You can use a lambda to wrap the funtion:
map(lambda x: sorted(x, reversed=True), l)
or:
map(lambda i, j: pow(i, j), list,itertools.repeat(x))
There are many ways to do it.
You could use functools.partial. It creates a partial, for the lack of a better word, of the function you pass to it. It sort of creates a new function with some parameters already passed into it.
For your example, it would be:
from functools import partial
rev_sort = partial(sorted, reverse=True)
map(rev_sort, l)
The other way is using a simple lambda:
map(lambda arr: sorted(arr, reverse=True), l)
The other other way (my personal choice), is using generators:
(sorted(arr, reverse=True) for arr in l)
For this specific case, you can also use a list comprehension -
l=[[1,2,3],[4,5,6],[7,8,9]]
l = [list(reversed(sublist)) for sublist in l]
//[[3,2,1],[6,5,4],[9,8,7]]

modifying argument value within function

I am trying to figure out a way to modify the order of a list of tuples within a function without returning the list.
For example:
L = [(2,4),(8,5),(1,3),(9,4)]
def sort_ratios(L):
L = sorted(L, key=lambda x: float(x[0])/float(x[1]))
return L
Thus, calling sort_ratios() outputs:
>>>sort_ratios(L)
[(1,3),(2,4),(8,5),(9,4)]
But L would still be [(2,4),(8,5),(1,3),(9,4)]
Instead, I would like to simply modify the value of L without returning anything so that sort_ratios() operates as follows:
>>>sort_ratios(L)
>>>L
[(1,3),(2,4),(8,5),(9,4)]
It seems trivial, but I just can't seem to get the function to operate this way.
Try L.sort(key=lambda x: float(x[0])/float(x[1])) for an in-place sort.

map,lambda and append.. why doesn't it work?

So I'm trying to do this.
a = []
map(lambda x: a.append(x),(i for i in range(1,5)))
I know map takes a function but so why doesn't it append to the list? Or is append not a function?
However printing a results to a still being empty
now an interesting thing is this works
a = []
[a.append(i) for i in range(5)]
print(a)
aren't they basically "saying" the same thing?
It's almost as if that list comprehension became some sort of hybrid list-comprehension function thing
So why doesn't the lambda and map approach work?
I am assuming you are using Python 3.x , the actual reason why your code with map() does not work is because in Python 3.x , map() returns a generator object , unless you iterate over the generator object returned by map() , the lambda function is not called . Try doing list(map(...)) , and you should see a getting filled.
That being said , what you are doing does not make much sense , you can just use -
a = list(range(5))
append() returns None so it doesn't make sense using that in conjunction with map function. A simple for loop would suffice:
a = []
for i in range(5):
a.append(i)
print a
Alternatively if you want to use list comprehensions / map function;
a = range(5) # Python 2.x
a = list(range(5)) # Python 3.x
a = [i for i in range(5)]
a = map(lambda i: i, range(5)) # Python 2.x
a = list(map(lambda i: i, range(5))) # Python 3.x
[a.append(i) for i in range(5)]
The above code does the appending too, however it also creates a list of None values as the size of range(5) which is totally a waste of memory.
>>> a = []
>>> b = [a.append(i) for i in range(5)]
>>> print a
[0, 1, 2, 3, 4]
>>> print b
[None, None, None, None, None]
The functions map and filter have as first argument a function reference that is called for each element in the sequence (list, tuple, etc.) provided as second argument AND the result of this call is used to create the resulting list
The function reduce has as first argument a function reference that is called for first 2 elems in the sequence provided as second argument AND the result is used together with the third elem in another call, then the result is used with the fourth elem, and so on. A single value results in the end.
>>> map(lambda e: e+10, [i for i in range(5)])
[10, 11, 12, 13, 14]
>>> filter(lambda e: e%2, [i for i in range(5)])
[1, 3]
>>> reduce(lambda e1, e2: e1+e2, [i for i in range(5)])
10
Explanations:
map example: adds 10 to each elem of list [0,1,2,3,4]
filter example: keeps only elems that are odd of list [0,1,2,3,4]
reduce example: add first 2 elems of list [0,1,2,3,4], then the result and the third elem of list, then the result and fourth elem, and so on.
This map doesn't work because the append() method returns None and not a list:
>>> a = []
>>> type(a.append(1))
<class 'NoneType'>
To keep it functional why not use reduce instead?
>>> from functools import reduce
>>> reduce(lambda p, x: p+[x], (i for i in range(5)), [])
[0, 1, 2, 3, 4]
Lambda function will not get triggered unless you wrap the call to map function in list() like below
list(map(lambda x: a.append(x),(i for i in range(1,5))))
map only returns a generator object which needs to be iterated in order to create a list. Above code will get the lambda called.
However this code does not make much sense considering what you are trying to achieve

Misunderstanding of python 3 map [duplicate]

primes = [2,3,5,7..] (prime numbers)
map(lambda x:print(x),primes)
It does not print anything.
Why is that?
I've tried
sys.stdout.write(x)
too, but doesn't work either.
Since lambda x: print(x) is a syntax error in Python < 3, I'm assuming Python 3. That means map returns a generator, meaning to get map to actually call the function on every element of a list, you need to iterate through the resultant generator.
Fortunately, this can be done easily:
list(map(lambda x:print(x),primes))
Oh, and you can get rid of the lambda too, if you like:
list(map(print,primes))
But, at that point you are better off with letting print handle it:
print(*primes, sep='\n')
NOTE: I said earlier that '\n'.join would be a good idea. That is only true for a list of str's.
This works for me:
>>> from __future__ import print_function
>>> map(lambda x: print(x), primes)
2
3
5
7
17: [None, None, None, None]
Are you using Python 2.x where print is a statement, not a function?
Alternatively, you can unpack it by putting * before map(...) like the following
[*map(...)]
or
{*map(...)}
Choose the output you desire, a list or a dictionary.
Another reason why you could be seeing this is that you're not evaluating the results of the map function. It returns a generator (an iterable) that evaluates your function lazily and not an actual list.
primes = [2,3,5,7]
map(print, primes) # no output, because it returns a generator
primes = [2,3,5,7]
for i in map(print, primes):
pass # prints 2,3,5,7
Alternately, you can do list(map(print, primes)) which will also force the generator to be evaluated and call the print function on each member of your list.

loop for inside lambda

I need to simplify my code as much as possible: it needs to be one line of code.
I need to put a for loop inside a lambda expression, something like that:
x = lambda x: (for i in x : print i)
Just in case, if someone is looking for a similar problem...
Most solutions given here are one line and are quite readable and simple. Just wanted to add one more that does not need the use of lambda(I am assuming that you are trying to use lambda just for the sake of making it a one line code).
Instead, you can use a simple list comprehension.
[print(i) for i in x]
BTW, the return values will be a list on None s.
Since a for loop is a statement (as is print, in Python 2.x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys.stdout along with the join method.
x = lambda x: sys.stdout.write("\n".join(x) + "\n")
To add on to chepner's answer for Python 3.0 you can alternatively do:
x = lambda x: list(map(print, x))
Of course this is only if you have the means of using Python > 3 in the future... Looks a bit cleaner in my opinion, but it also has a weird return value, but you're probably discarding it anyway.
I'll just leave this here for reference.
anon and chepner's answers are on the right track. Python 3.x has a print function and this is what you will need if you want to embed print within a function (and, a fortiori, lambdas).
However, you can get the print function very easily in python 2.x by importing from the standard library's future module. Check it out:
>>>from __future__ import print_function
>>>
>>>iterable = ["a","b","c"]
>>>map(print, iterable)
a
b
c
[None, None, None]
>>>
I guess that looks kind of weird, so feel free to assign the return to _ if you would like to suppress [None, None, None]'s output (you are interested in the side-effects only, I assume):
>>>_ = map(print, iterable)
a
b
c
>>>
If you are like me just want to print a sequence within a lambda, without get the return value (list of None).
x = range(3)
from __future__ import print_function # if not python 3
pra = lambda seq=x: map(print,seq) and None # pra for 'print all'
pra()
pra('abc')
lambda is nothing but an anonymous function means no need to define a function like def name():
lambda <inputs>: <expression>
[print(x) for x in a] -- This is the for loop in one line
a = [1,2,3,4]
l = lambda : [print(x) for x in a]
l()
output
1
2
3
4
We can use lambda functions in for loop
Follow below code
list1 = [1,2,3,4,5]
list2 = []
for i in list1:
f = lambda i: i /2
list2.append(f(i))
print(list2)
First of all, it is the worst practice to write a lambda function like x = some_lambda_function. Lambda functions are fundamentally meant to be executed inline. They are not meant to be stored. Thus when you write x = some_lambda_function is equivalent to
def some_lambda_funcion():
pass
Moving to the actual answer. You can map the lambda function to an iterable so something like the following snippet will serve the purpose.
a = map(lambda x : print(x),[1,2,3,4])
list(a)
If you want to use the print function for the debugging purpose inside the reduce cycle, then logical or operator will help to escape the None return value in the accumulator variable.
def test_lam():
'''printing in lambda within reduce'''
from functools import reduce
lam = lambda x, y: print(x,y) or x + y
print(reduce(lam,[1,2,3]))
if __name__ =='__main__':
test_lam()
Will print out the following:
1 2
3 3
6
You can make it one-liner.
Sample
myList = [1, 2, 3]
print_list = lambda list: [print(f'Item {x}') for x in list]
print_list(myList)
otherList = [11, 12, 13]
print_list(otherList)
Output
Item 1
Item 2
Item 3
Item 11
Item 12
Item 13

Categories