1

In Python how the title() method can be used?

Is it only for a single item or also for a whole list?

The first print works, the second returns an error. Why?

animals = ['dog', 'cat', 'whale', 'koala', 'panda']
print(f"\nname of the 3rd animal: {animals[2].title()}")
print(f"\nname of all animals: {animals.title()}")

The first print works, the second returns an error. Why?

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
maxval
  • 49
  • 1
  • 4
  • 2
    *"Why?"* — Because `title` is a method on string objects, not list objects. – deceze Apr 25 '23 at 13:56
  • 1
    You can apply it to all the strings in the list. And join them together: `", ".join(map(str.title, animals))` – Jab Apr 25 '23 at 13:58

1 Answers1

5

It doesn't work because list doesn't have a title method. You need to loop over the elements.

One option is to use a list comprehension:

print(f"name of all animals: {', '.join([a.title() for a in animals])}")

Output:

name of all animals: Dog, Cat, Whale, Koala, Panda
timings for the aficionados
# list_comp
', '.join([a.title() for a in l])

# generator
', '.join(a.title() for a in l)

# map_generator
', '.join(map(str.title, l))

# map_list
', '.join(list(map(str.title, l)))

# join_title
', '.join(l).title()

enter image description here

mozway
  • 194,879
  • 13
  • 39
  • 75
  • 1
    FWIW, the `[]` are superfluous… – deceze Apr 25 '23 at 13:58
  • 2
    @deceze they are not, [`join` is more efficient on a list than a generator](https://stackoverflow.com/questions/37782066/list-vs-generator-comprehension-speed-with-join-function) (it requires to know the size of the iterable). I agree it would work without the brackets but I put them on purpose ;) – mozway Apr 25 '23 at 13:59
  • 1
    Curious @mozway, if map was used like in my comment, wouldn't it have a `length_hint`? Would it be more efficient to use map and list or the comprehension? – Jab Apr 25 '23 at 14:02
  • 2
    Fair enough, I'd still probably write it without. :o) – deceze Apr 25 '23 at 14:03
  • 1
    @Jab `', '.join(list(map(str.title, animals)))` is a bit more efficient than `', '.join([a.title() for a in animals])` and `', '.join(map(str.title, animals))` in a test on 6M items. – mozway Apr 25 '23 at 14:06
  • 2
    Just realized `', '.join(animals).title()` would actually be the most efficient and actually more readable. – Jab Apr 25 '23 at 14:06
  • @Jab yes that's true, good one! (but OP should be aware that this only works because of this particular method) – mozway Apr 25 '23 at 14:10
  • @Jab yes, in the case of join+title specifically, because of how title works. But I think everyone here tries to make it more general/keep it as a list until the very end because no details from OP. :) – h4z3 Apr 25 '23 at 14:11
  • Since there was some info about "more efficient": the difference is really small. Since @mozway mentioned test on 6M items, I did my own of similar size (10M, each of length 100 - just did `my_list = [string.printable] * 10000000` because I'm lazy) and the time difference depends more on what my machine is doing than on type of the iterable passed to join (I had map be 11.25s once and 13.12s another time). One would need to time and average a lot of runs to actually determine which is faster. (timeit by default wants to do 1M runs) – h4z3 Apr 25 '23 at 14:22
  • "It doesn't work because list doesn't have a title method." thanks – maxval Apr 25 '23 at 14:23
  • as I was finishing the above comment, @mozway uploaded the graph - please explain how many repetitions you did to make it comparable – h4z3 Apr 25 '23 at 14:24
  • @h4z3 the x-axis is the number of items in the list, the y-axis is the runtime. I think perfplot only runs once each combination, but the fact that it tests many combinations enables to see non-dependent variability (=noise). I also tested with `%%timeit`, which makes between 7 and 100,000 repetitions and observed a significant (but small) difference. – mozway Apr 25 '23 at 18:56