-2

I am trying to use the map() function and capitalize all the words in the list.

my_pets = ['sisi', 'bibi', 'titi', 'carla']

def capitalizing(a):
    for item in a:
        b = item.upper()
        return b

print(list(map(capitalizing, my_pets)))

If I run this code, I get the output as following:

['S', 'B', 'T', 'C']

Why is that? Why does the code just runs the first letter and stops for each word?

I already know that the "for" loop/iteration is incorrect to get all the words, I don't need it, but why is this loop runs for the first letter of each word?

Thanks for your assistance in advance.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
rodny9
  • 53
  • 1
  • 4
  • @rodny9 I fixed your code format, can you confirm this is the same indentation you have? – Olivier Melançon Jun 28 '20 at 17:19
  • you don't need to use for loop if you are using `map()` – deadshot Jun 28 '20 at 17:23
  • map is already iterating on each element before giving it (the string element) to capitalizing. for item in a: is iterating on the characters of the string. return b returns the first character immediately at the first iteration, exiting the function after one iteration – user120242 Jun 28 '20 at 17:24
  • 1
    `print(list(map(str.upper, my_pets)))` – deadshot Jun 28 '20 at 17:26
  • 1
    You can use a list comprehension, ``[x.upper() for x in ['sisi', 'bibi', 'titi', 'carla']]`` – sushanth Jun 28 '20 at 17:30

4 Answers4

1

The role of map is to take care of the iterating-over-the-input-sequence bit for you, so the function that you supply to map should be defined in such a way that it takes in only one element of the sequence as argument.

The way it's provided in the OP, map takes each element of the original list (i.e. a name) and applies capitalizing to each one in turn. However, the function internally loops over its argument (which, in this case, are the characters in the name string) and returns the upper case of the first character in each name. (Can you see why?)

As others have suggested, there are simpler/cleaner ways to achieve this, but if you are trying to understand how map works, remove the for loop and simply return a.upper().

navneethc
  • 1,234
  • 8
  • 17
0

return returns the value and exits the function. Normally you would want to use yield to return multiple values, but you don't actually need a loop at all:

def capitalizing(a):
    return a.upper()

In fact you don't even need capitalizing since it's just a wrapper on str.upper:

>>> print(list(map(str.upper, my_pets)))
['SISI', 'BIBI', 'TITI', 'CARLA']

Or even better, use a list comprehension instead:

>>> print([s.upper() for s in my_pets])
['SISI', 'BIBI', 'TITI', 'CARLA']
wjandrea
  • 28,235
  • 9
  • 60
  • 81
0

A more easy way to understand map,

print(list(map(lambda s: s.upper(), ['sisi', 'bibi', 'titi', 'carla'])))
Aviik
  • 11
  • 1
  • 6
  • [I hate list(map(lambda))](https://stackoverflow.com/a/61945553/4518341). Use a list comprehension instead: `print([s.upper() for s in my_pets])`. Much shorter and cleaner, right? – wjandrea Jun 28 '20 at 17:38
  • There is a difference in the time complexity. read this [https://leadsift.com/loop-map-list-comprehension/](https://leadsift.com/loop-map-list-comprehension/) – Aviik Jun 28 '20 at 18:09
  • That page says a list comp is faster than a map except for "Result required O(n)", where the difference is marginal. Also those results seem to be for Python 2. I don't know if things have changed in Python 3, but the additional cast to `list` might add some overhead. – wjandrea Jun 28 '20 at 18:19
  • Constructing the `map` object might also require some overhead. – wjandrea Jun 28 '20 at 18:25
  • Find this method "(λx.x) List" very much close to map method. – Aviik Jun 28 '20 at 18:34
0

Your placement of return inside the for loop, causes it to return after the first iteration (on the first character of the string passed to capitalizing). eg:
capitalizing('sisi')

for item in a:     # a = 'sisi'
  b = item.upper() # item = 's', b = 'S'
  return b         # b = 'S', return 'S' and exit function

The code can be written more concisely, as the other answers have shown. This code is doing things redundantly.

Here is a fixed version of your code, to return after the for loop is finished building the string, and not after the first iteration:

my_pets = ['sisi', 'bibi', 'titi', 'carla']

def capitalizing(a):
    b = ""
    for item in a:
        b += item.upper()
        # using return here will exit the function immediately after the first iteration
    return b # return after finishing

print(list(map(capitalizing, my_pets)))
user120242
  • 14,918
  • 3
  • 38
  • 52