Here are our solutions for the day 20 exercises in the 30 Days of Python series. Make sure you try the exercises yourself before checking out the solutions!

### 1) Use `map` to call the `strip` method on each string in the following list. Print the lines of the nursery rhyme on different lines in the console.

``````humpty_dumpty = [
"  Humpty Dumpty sat on a wall,  ",
"Humpty Dumpty had a great fall;     ",
"  All the king's horses and all the king's men ",
"    Couldn't put Humpty together again."
]
``````

First, let's try to tackle this by defining a separate function to perform the strip on a given line. I'm going to call mine `line_stripper`, but you can call it whatever you like.

``````def line_stripper(line):
return line.strip()
``````

Now we can write our `map` call. When calling `map`, we need to first pass in the function we want to call, and then we pass in the iterables we want to grab arguments from. In this case, we just have a single iterable: `humpty_dumpty`.

We can then unpack the `map` object and pass it to `print`.

``````def line_stripper(line):
return line.strip()

humpty_dumpty = [
"  Humpty Dumpty sat on a wall,  ",
"Humpty Dumpty had a great fall;     ",
"  All the king's horses and all the king's men ",
"    Couldn't put Humpty together again."
]

print(*map(line_stripper, humpty_dumpty), sep="\n")
``````

If you prefer, you could also use a `for` loop to print the values.

Instead of defining this `line_stripper` function, we could also use a lambda expression:

``````humpty_dumpty = [
"  Humpty Dumpty sat on a wall,  ",
"Humpty Dumpty had a great fall;     ",
"  All the king's horses and all the king's men ",
"    Couldn't put Humpty together again."
]

print(*map(lambda line: line.strip(), humpty_dumpty), sep="\n")
``````

But we could also use the `methodcaller` function from the `operator` module if we didn't want to define function using lambda.

``````from operator import methodcaller

humpty_dumpty = [
"  Humpty Dumpty sat on a wall,  ",
"Humpty Dumpty had a great fall;     ",
"  All the king's horses and all the king's men ",
"    Couldn't put Humpty together again."
]

print(*map(methodcaller("strip"), humpty_dumpty), sep="\n")
``````

Any of these approaches is perfectly fine.

### 2) Below you'll find a tuple containing several names. Use a list comprehension with a filtering condition so that only names with fewer than 8 characters end up in the new list. Make sure that every name in the new list is in title case.

``````names = ("bob", "Christopher", "Rachel", "MICHAEL", "jessika", "francine")
``````

First let's just create a comprehension to turn the names to lowercase. We can add the filtering condition once we know it works.

``````names = ("bob", "Christopher", "Rachel", "MICHAEL", "jessika", "francine")
names = [name.title() for name in names]
``````

A quick print of `names` shows that we don't have any issues, so now we need to add our filter. In this case, we want to check whether or not the name contains less than 8 characters.

We can find out how many characters are in a string using the `len` function, and we can compare the result against `8` using `<`.

``````names = ("bob", "Christopher", "Rachel", "MICHAEL", "jessika", "francine")
names = [name.title() for name in names if len(name) < 8]
``````

If you're curious as to how we replicate something like this with `map` and `filter`, we can pass the result of calling `filter` to `map` like this:

``````from operator import methodcaller

names = ("bob", "Christopher", "Rachel", "MICHAEL", "jessika", "francine")
names_title = map(methodcaller("title"), filter(lambda name: len(name) < 8, names))
``````

For situations like this where we need to perform a modification and we need to do some filtering, the comprehension syntax is usually a lot neater and easier to understand.

### 3) Use `filter` to remove all negative numbers from the following range: `range(-5, 11)`. Print the remaining numbers to the console.

We can actually do this on in one line if we want to like so:

``````print(*filter(lambda number: number >= 0, range(-5, 11)))
``````

Here we're saying that for every number in `range(-5, 11)`, keep the number if it's greater than `0`. Then we're unpacking the `filter` object using `*`, so that we get access to the values we've kept.

This is extremely succinct; however, in this case, I think it makes a lot of sense to create a separate function for our `filter` predicate.

``````def is_positive(number):
return number >= 0

print(*filter(is_positive, range(-5, 11)))
``````