21

I am told to

Write a function, square(a), that takes an array, a, of numbers and returns an array containing each of the values of a squared.

At first, I had

def square(a):
    for i in a: print i**2

But this does not work since I'm printing, and not returning like I was asked. So I tried

    def square(a):
        for i in a: return i**2

But this only squares the last number of my array. How can I get it to square the whole list?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user1692517
  • 1,122
  • 4
  • 14
  • 28

8 Answers8

43

You could use a list comprehension:

def square(list):
    return [i ** 2 for i in list]

Or you could map it:

def square(list):
    return map(lambda x: x ** 2, list)

Or you could use a generator. It won't return a list, but you can still iterate through it, and since you don't have to allocate an entire new list, it is possibly more space-efficient than the other options:

def square(list):
    for i in list:
        yield i ** 2

Or you can do the boring old for-loop, though this is not as idiomatic as some Python programmers would prefer:

def square(list):
    ret = []
    for i in list:
        ret.append(i ** 2)
    return ret
Waleed Khan
  • 11,426
  • 6
  • 39
  • 70
  • Good that you point out a lot of methods. However, most established solutions are based on list comprehension or numpy. For performance of `map` in combination with `lambda`, have a look at http://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map – Dr. Jan-Philip Gehrcke Sep 23 '12 at 19:27
  • Thank you! I used the comprehension method. Will be looking more into that method. – user1692517 Sep 23 '12 at 19:28
  • "This is not as idiomatic as some Python programmers would prefer" - I completely agree, but it's worth pointing out that there are situations in which the only practical option is to append to a list. The best example I can think of is if the generator needs to 'remember' the numbers it has previously returned so as not to return duplicates or get into a cycle. – Benjamin Hodgson Sep 23 '12 at 22:14
  • up voted for the O(1) space complexity map solution – Coder Dec 25 '20 at 06:46
36

Use a list comprehension (this is the way to go in pure Python):

>>> l = [1, 2, 3, 4]
>>> [i**2 for i in l]
[1, 4, 9, 16]

Or numpy (a well-established module):

>>> numpy.array([1, 2, 3, 4])**2
array([ 1,  4,  9, 16])

In numpy, math operations on arrays are, by default, executed element-wise. That's why you can **2 an entire array there.

Other possible solutions would be map-based, but in this case I'd really go for the list comprehension. It's Pythonic :) and a map-based solution that requires lambdas is slower than LC.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Dr. Jan-Philip Gehrcke
  • 33,287
  • 14
  • 85
  • 130
9
import numpy as np
a = [2 ,3, 4]
np.square(a)
user3503711
  • 1,623
  • 1
  • 21
  • 32
2

Use numpy.

import numpy as np
b = list(np.array(a)**2)
tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • 2
    Numpy for such a trivial problem seems like overkill. – Waleed Khan Sep 23 '12 at 19:24
  • 1
    Fair point, but where you have the need to square lists, you soon need to start doing other operations with them and there is no reason re-invent the wheel. – tacaswell Sep 23 '12 at 19:27
  • Is there a way to avoid having to use np.array and just use array(a)**2? – user1936752 Feb 29 '16 at 10:04
  • @user1936752 No, because the "to the power of" function on standard arrays isn't defined. However, it's defined on `numpy` arrays, because they aren't really arrays; they are a special data type created by the `numpy` module. – wizzwizz4 May 22 '16 at 18:35
1
def square(a):
    squares = []
    for i in a:
        squares.append(i**2)
    return squares
Curious
  • 2,783
  • 3
  • 29
  • 45
0

One more map solution:

def square(a):
    return map(pow, a, [2]*len(a))
hendrik
  • 1,902
  • 16
  • 14
0
def square(a):
    squares = []
    for i in a:
        squares.append(i**2)
    return squares

so how would i do the square of numbers from 1-20 using the above function

Mureinik
  • 297,002
  • 52
  • 306
  • 350
Abrham Yep
  • 11
  • 1
0

you can do

square_list =[i**2 for i in start_list]

which returns

[25, 9, 1, 4, 16]  

or, if the list already has values

square_list.extend([i**2 for i in start_list])  

which results in a list that looks like:

[25, 9, 1, 4, 16]  

Note: you don't want to do

square_list.append([i**2 for i in start_list])

as it literally adds a list to the original list, such as:

[_original_, _list_, _data_, [25, 9, 1, 4, 16]]
9 Guy
  • 176
  • 3
  • 14
  • 1
    Note: `square_list.extend()` does not return anything as this is an in place operation. – AChampion Sep 12 '20 at 08:10
  • @AChampion you are correct, i'll edit to make it more accurate. Also its funny to look at myself from 4 years ago talk wow – 9 Guy Sep 22 '20 at 01:44