1

When list of tuples are used in for loop it works perfectly with two separate variables as below

t_dict = {
    "k1": "v1",
    "k2": "v2",
    "k3": "v3",
    "k4": "v4",
    "k5": "v5"
}

for k, v in t_dict.items():
    print "%s=%s" % (k, v)

But when converted into lambda with map function got an error as below

print map(lambda k, v: "%s=%s" % (k, v), t_dict.items())

Traceback (most recent call last):   File "test.py", line 14, in <module>
    print map(lambda k, v: "%s=%s" % (k, v), t_dict.items()) TypeError: <lambda>() takes exactly 2 arguments (1 given)

Is there any other way to call list of tuple in lambda function?

jpp
  • 159,742
  • 34
  • 281
  • 339
va1bhav
  • 365
  • 1
  • 5
  • 21

4 Answers4

3

Built-in map supports multiple iterables:

res = map(lambda k, v: "%s=%s" % (k, v), t_dict, t_dict.values())
# ['k1=v1', 'k2=v2', 'k3=v3', 'k4=v4', 'k5=v5']

As described in the docs for map:

If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel.

jpp
  • 159,742
  • 34
  • 281
  • 339
  • there should be a more elegant way, `map('{}={}'.format, t_dict, t_dict.values())` is the best I could think of – Chris_Rands Jan 14 '19 at 10:06
  • @Chris_Rands, Yup, good point. However, I wanted to advise OP on the more general issue of how to use a multi-argument function with `map`. – jpp Jan 14 '19 at 10:07
1

For you case, you can also use the tuple after the % for formatting, so:

map(lambda t: "%s=%s" % t, t_dict.items())
mfrackowiak
  • 1,294
  • 8
  • 11
1

As already suggested, you can pass multiple iterables to map, but if you want to pass the items and not keys and values individually, you can use zip(*...) to "transpose" the items to two lists and use * again to pass those as two different arguments to map:

>>> list(map(lambda k, v: "%s=%s" % (k, v), *zip(*t_dict.items())))
['k1=v1', 'k2=v2', 'k3=v3', 'k4=v4', 'k5=v5']

Or use itertools.starmap:

>>> from itertools import starmap
>>> list(starmap(lambda k, v: "%s=%s" % (k, v), t_dict.items()))
['k1=v1', 'k2=v2', 'k3=v3', 'k4=v4', 'k5=v5']
tobias_k
  • 81,265
  • 12
  • 120
  • 179
  • 1
    @Chris_Rands Yes, that's nicer that the `lambda`, but it's still a function taking two paramters, thus this does not really change anything about the core issue. – tobias_k Jan 14 '19 at 10:12
0

Other option is this way (str.join(iterable)) to get the list of strings:

map( lambda t: "=".join(t), t_dict.items() )
#=> ['k3=v3', 'k2=v2', 'k1=v1', 'k5=v5', 'k4=v4']

This version can also print out:

import sys
map( lambda t: sys.stdout.write("=".join(t) + "\n"), t_dict.items() )

# k3=v3
# k2=v2
# k1=v1
# k5=v5
# k4=v4
iGian
  • 11,023
  • 3
  • 21
  • 36