How to iterate over a list do an action to each item and add the new item to a new list?

How am I able to iterate over a list of items in an assignment using a for loop, do something to each item ex (if value is over 80 rename to ‘A’), then take each item if the list and add it to a new empty list. Can I do this without using the append function

There are two options:

  • return a new list
  • modify the list in place.

Let’s do the last, first:

a = [35, 21, 55, 48, 89, 74, 17, 94, 86]
n = range(len(a))
for i in n:
    if a[i] > 80:
        a[i] = 'A'

print (a)
[35, 21, 55, 48, 'A', 74, 17, 'A', 'A']

Note that to be able to modify a list in place we need to access by index, hence using the range() object to generate a sequence of matching length.

If we wish to return a new list, then we don’t need the indices. We can iterate over the values directly: However in this next example we will be using the indices and a premade list of matching length.

a = [35, 21, 55, 48, 89, 74, 17, 94, 86]
n = len(a)
b = [None] * n
for i in range(n):
    x = a[i]
    b[i] = 'A' if x > 80 else x

print (b)
[35, 21, 55, 48, 'A', 74, 17, 'A', 'A']

Note that we did not use append() but we have to create a mock list to start.

Another way to not have to use append is to use list comprehension. This might be a new concept to you so please bear with us. The concept will come up early in list lessons so is not that far afield.

a = [35, 21, 55, 48, 89, 74, 17, 94, 86]
b = ['A' if x > 80 else x for x in a]

print (b)
[35, 21, 55, 48, 'A', 74, 17, 'A', 'A']

Note that we have iterated directly over the values in a and have no need to reference indices.

For all its simplicity, list comprehension can take a minute to get one’s head around and some practice to master. Hold off until it comes up in the lessons if it has not yet surfaced.


Extra Study

When you get list comprehension under your belt, and have learned all the mathematical operators, and have learned about dictionaries and their methods, study how we convert grade scores to letter grades in a single comprehension:

>>> g = {
...     60: 'D',
...     70: 'C',
...     80: 'B',
...     90: 'A',
...     100: 'A+'
... }
>>> a = [65, 71, 55, 68, 89, 74, 100, 94, 86]
>>> [g.get(x // 10 * 10, 'F') for x in a]
['D', 'C', 'F', 'D', 'B', 'C', 'A+', 'A', 'B']

Above we use both a dictionary to look up grades and return associated letter, and a list to contain the grade scores. Because we are using a read only for loop we don’t need to care about the length of the list.

Our output expression applies floor division and multiplication to arrive at a lookup argument for the get() method to evaluate. If no value is returned from the lookup it defaults to, 'F'.

Now one might ask, what is the arithmetic doing? Two things, first we divide by 10 but only keep the integer portion of the quotient. Multiply by 10 to restore the base grade score, which we can now look up in the dictionary.

We use no logic other that what is intuitively built in to the construct. This is one approach that very few learners will come up with given their focus on logical constructs and control flow. Don’t feel like it is a deficiency on one’s part if this doesn’t come intuitively in your early learning stages.

It’s gets more interesting…

>>> sorted(zip(a, [g.get(x // 10 * 10, 'F') for x in a]), reverse=True)
[(100, 'A+'), (94, 'A'), (89, 'B'), (86, 'B'), (74, 'C'), (71, 'C'), (68, 'D'), (65, 'D'), (55, 'F')]

sorted() and zip() if new, are coming right over the horizon. In the above sorted() consumes the zip object, but does not consume a. Our comprehension is one of the arguments so fades into history as soon as it is handed over to zip(). This will make more sense when one learns about iterators.

It gets better, still…

>>> g = {60: 'D', 70: 'C',80: 'B', 90: 'A', 100: 'A+'}
>>> p = ['CP', 'PJ', 'QB', 'BB', 'WL', 'OT', 'JE', 'KO', 'WT']
>>> a = [65, 71, 55, 68, 89, 74, 100, 94, 86]
>>> sorted(zip(p, a, [g.get(x // 10 * 10, 'F') for x in a]), key=lambda u: u[1], reverse=True)
[('JE', 100, 'A+'), ('KO', 94, 'A'), ('WL', 89, 'B'), ('WT', 86, 'B'), ('OT', 74, 'C'), ('PJ', 71, 'C'), ('BB', 68, 'D'), ('CP', 65, 'D'), ('QB', 55, 'F')]

It takes the brain a good long time and lots and lots of practice, debugging, refining, experimenting, reading and just plain hard work to build up one’s tool chest to this extent. Our aim here is not to show a better way, only that there are many ways to accomplish our end goal. Always keep an open mind as you learn, and never be afraid to admit that one’s work can always be improved or refactored. That is the real joy of learning to program: Being able to come at a problem from all angles.

Happy coding!