How to create a list from another list according to a function

Question:

I would like to create a list which has values which correspond to another list.
For example if I had:

listA = [1, 2, 3, 4, 5,...]

and I would like to create another list which is the same, except all the values were varied according to x^2 (or any other function), giving:

listB = [1, 4, 9, 16,25, ...]

I have already tried to do this by doing a while loop:

listA = [1, 2, 3, 4]
listB = range(1, 4, 1)
i = 0
while i <= 4:
    listB [i] = (listA [i]) ** 2
    i = i + 1
print listA
print listB

But it just spits out an error message:

Traceback (most recent call last):
  File "/home/tim/Desktop/Python/test.py", line 5, in <module>
    listB [i] = (listA [i]) ** 2
IndexError: list assignment index out of range
Asked By: Tim Robson

||

Answers:

You can try this, using a lambda function to apply whatever change you want to each element in the list. In this case, the function is squaring every value in the list:

listA = [1, 2, 3, 4, 5,...]

operation = lambda x:x**2

new_list = map(operation, listA)

Also, you can perform the function operation in list comprehension:

new_list = [i**2 for i in listA]
Answered By: Ajax1234

There is a smart syntax for building lists out of others:

listB = [x*x for x in listA]

Edit: Never use range as a list directly, even if it makes a list in Python 2, because it spits out a range object in Python 3. Use list(range(...)) instead!

The popular numpy library provides a more concise syntax for doing such list operations, when the list would only consist out of numbers. It uses arrays that are faster in some circumstances like the element wise multiplication. The statement above can be rewritten as:

arrayB = arrayA * arrayA

or

arrayB = arrayA ** 2

or (not always recommended)

f = lambda a: a**2
arrayB = f(arrayA)

The element wise multiplication is sometimes referred to as the hadamard product, that comes from vector arithmetics (there is also a@b in numpy). In numpy you have to create the arrays with np.array or np.arange. The last is similar to range in Python 2 in the way, that it creates an array directly.

Answered By: cmdLP

You can use the numpy library with a function called power

import numpy as np

listA = [1,2,3,4]

new_li = np.power(listA, 2)

print new_li

>>> [ 1  4  9 16]    
Answered By: omri_saadon

There are multiple ways of doing what you are asking, others have pointed out list comprehensions and maps.

Reviewing your code:

listB = range(1, 4, 1)

The is only 3 items, [1, 2, 3], range() is up to but not including the stop arg. You don’t need to initialise your listB because you can just listB.append() in the loop, so listB = [] is sufficient. Note in python3 this assigns a range() object to listB and it doesn’t initialise the list as you intended.

i = 0
while i <= 4:

This loops 5 times, i = 0, 1, 2, 3, 4, and because this is more than listB (and listA) it results in the IndexError you are seeing. The normal way to do fixed loops would be with a for loop, e.g. for i in range(4):. However, you can loop directly over the elements in listA with for i in listA: and this would be considerd more pythonic

    listB [i] = (listA [i]) ** 2

This doesn’t work because your loop goes to from 0 to 4 (inclusive) and range(1, 4, 1) is only 3 items [1, 2, 3].

    i = i + 1

Unnecessary with a for loop.

Putting it all together and doing it iteratively as you’ve described you would do:

listA = [1, 2, 3, 4]
listB = []
for i in listA:
    listB.append(i**2)

print(listA)  # [1, 2, 3, 4]
print(listB)  # [1, 4, 9, 16]

Note: My preference would be for the list comprehension:

listB = [i**2 for i in listA]
Answered By: AChampion

Python provides the enumerate function when you need to iterate over a list and need the index. That way you avoid easy-to-avoid IndexErrors like these:

listA = [1, 2, 3, 4]
listB = [None]*4
for idx, item in enumerate(listA):
    listB[idx] = item ** 2

But in most cases you don’t even need to create listB beforehand, you could let Python create it for you with map or a “list comprehension”. The other answers already covered that but I wanted to share some way of using map without lambda:

import itertools
listB = list(map(pow, listA, itertools.repeat(2, len(listA))))

You can omit the outer list() if you’re using python 2.x.

Answered By: MSeifert

You can use a list comprehension:

listA = [1, 2, 3, 4]

listB = [x**2 for x in listA]

Or a normal loop:

listA = [1, 2, 3, 4]

listB = []
for x in listA:
    listB.append(x**2)
Answered By: Ender Look
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.