Listas e arrays (vetores)

até agora vimos variáveis que representam valores unicos de um dado tipo

em física é comum querer representar vários numeros com um nome como $\vec{r}=(x,y,z)$

Outro exemplo seria uma tabela com milhares de valores medidos para uma dada grandeza $a_1,a_2,a_3$ de modo que possamos usar $A={a_i}$ onde i é iterado no total de elementos de $A$

Python permite lidar com essas situações usando containers como listas e arrays, que são as mais importantes e tuples, dicionarios e conjuntos, que são menos comuns

Listas

o tipo mais básico de container em Python é a lista

uma lista é uma lista de quantidades, que não precisam ser do mesmo tipo

Em física no entanto, em geral usamos listas de elementos do mesmo tipo


In [3]:
lista = [2, 3.4, 'teste']   # sintaxe para definir uma lista
print lista

x = 3.0
y = 5.3

lista = [x**2, x+y, x**y, 2*x+5*y]  # usando expressões para definir listas
print lista


[2, 3.4, 'teste']
[9.0, 8.3, 337.8645683867659, 32.5]

tendo definido listas provavelmente vamos querer fazer operações com elas

os elementos de uma lista podem ser recuperados pela sua posição de alocação

considere a lista l=[3, 5, 2, 45, 23] onde temos os seguintes elementos individuais:

l[0] é 3, l[1] é 5, l[2] é 2 e assim por diante

note que a indexação se inicia em 0, ou seja, l[0] é o primeiro elemento da lista

os elementos individuais funcionam como variáveis únicas


In [5]:
from math import sqrt

r = [1.0, 1.5, -2.2]
tamanho = sqrt( r[0]**2 + r[1]**2 + r[2]**2 )   # calculando o módulo de um vetor
print tamanho

# podemos mudar o valor de elementos individuais na lista:
r[1] = 3.5
print r


2.84429253067
[1.0, 3.5, -2.2]

uma capacidade importante e poderosa em Python é a de poder fazer operações com listas

Algumas usuais são: sum, max, min, len, mean


In [7]:
r = [1.0, 1.5, -2.2]
total = sum(r)           # essa função retorna a soma de todos os elementos da lista
print total

print max(r), min(r)     # maximo e minimo da lista r

print len(r)            # tamanho da lista

media = sum(r)/len(r)   # calculando a média
print media


0.3
1.5 -2.2
3
0.1

Uma função especial em Python é a map. Ela permite aplicar funções a todos os elementos de uma lista


In [6]:
print dir+'file.txt'


ab

In [12]:
from math import log

r = [1.0, 1.5, 2.2]

logr = list(map(log, r))
print logr, type(logr)


[0.0, 0.4054651081081644, 0.7884573603642703] <type 'list'>

outra possibilidade importante com listas em Python é a abilidade de adicionar ou remover elementos


In [2]:
r = [1.0, 1.5, 2.2]
r.append(6.2)
print r

x= 3
r.append(2*x+1)
print r


[1.0, 1.5, 2.2, 6.2]
[1.0, 1.5, 2.2, 6.2, 7]

pode-se criar uma lista vazia e ir adicionando elementos a medida que o programa evolui


In [17]:
r=[]
i = 0
while i < 10:
    r.append(i)
    i += 1
print r

# removendo elementos
r.pop()
print r

# removendo um elemento específico
r.pop(3)
print r


[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 4, 5, 6, 7, 8]

Arrays

arrays são semelhantes a listas, mas existem diferenças importantes:

1 - arrays tem tamanho fixo e não podem ser alterados depois de criados
2 - arrays tem que ter todos os elementos do mesmo tipo

mas arrays tem vantagens: podem ser multidimensionais, se comportam como vetores, podemos fazer aritmética com eles ( o que não funciona com listas) e as operações com eles são mais rápidas em geral.

antes de usar um array voce precisa cria-lo dizendo de que tipo será e com quantos elementos

o modulo em Python usado para lidar com arrays é o numpy


In [4]:
from numpy import zeros
a = zeros(4,float)
print a


[ 0.  0.  0.  0.]

note que os arrays são impressos de modo distinto das listas, sem virgula separando os elementos


In [5]:
a = zeros(10,int)        # array de inteiros
b = zeros(10,complex)    # array de complexos
c = zeros(10,str)        # array de strings

print a
print b
print c


[0 0 0 0 0 0 0 0 0 0]
[ 0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j  0.+0.j
  0.+0.j]
['' '' '' '' '' '' '' '' '' '']

In [9]:
# criando arrays multi dimensionais
from numpy import zeros

a = zeros([3,4,5],float)      # array de dimensões 3 linhas x 4 colunas
print a

print [[0,1],[2,3]]


[[[ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]]

 [[ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]]

 [[ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]
  [ 0.  0.  0.  0.  0.]]]
[[0, 1], [2, 3]]

outra maneira de se criar um array em numpy é usando a função array para converter uma lista:


In [11]:
from numpy import array

r = [ 1.0, 1.5, -2.2 ]   # lista
a = array(r,float)       # array
print a

# ou em uma unica linha:
a = array([1.0,1.5,-2.2],float)
print a


[ 1.   1.5 -2.2]
[ 1.   1.5 -2.2]

podemos também criar arrays multidimensionais definindo seus elementos:


In [12]:
a = array([[1,2,3],[4,5,6]],int)
print a


[[1 2 3]
 [4 5 6]]

a indexação funciona de maneira similar a listas


In [3]:
import numpy as np
# from numpy import zeros

a = np.zeros([10,10],int)
print a,'\n'

# mude o valor de alguns elementos
a[0,1] = 1
a[1,0] = -1

print a
print a[1:4,5:7]


[[0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]] 

[[ 0  1  0  0  0  0  0  0  0  0]
 [-1  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0  0  0  0]]
[[0 0]
 [0 0]
 [0 0]]

Aritimética com arrays

com em listas, os elementos dos arrays funcionam como variaveis isoladas.

poderíamos fazer algo como a[0] = a[1] + 1 com elemntos do array a

ou algo como x = a[2]*2 - 2a[3]/y

uma das grandes vantagens em Python é fazer aritimética com todo o vetor de uma vez:


In [10]:
from numpy import array

a = array([1,2,3,0],int)
b = 2*a

print a, '\n'
print b, '\n'
print b/a       # em casos como esse os arrays tem que ter o memso tamanho!


[1 2 3 0] 

[2 4 6 0] 

[2 2 2 0]
/home/hmonteiro/anaconda2/lib/python2.7/site-packages/ipykernel/__main__.py:8: RuntimeWarning: divide by zero encountered in divide

note que a multiplicação de arrays não funciona exatamente com em matemática, produto escalar de dois vetores:


In [19]:
a = array([1,2,3,4],int)
b = array([2,4,6,8],int)

print a*b


[ 2  8 18 32]

veja que o que aconteceu é que cada elemento foi multiplicado pelo seu correspondente no outro vetor

Para fazer opeções de algebra linear como produto escalar o numpy tem funções específicas. Veja a lista completa em: https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.linalg.html


In [20]:
from numpy import array,dot

a = array([1,2,3,4],int)
b = array([2,4,6,8],int)

print dot(a,b)             # imprime o produto escalar de a e b


60

operações com matrizes podem ser feitas de maneira simples.

Seja a operação:

$\left( \begin{array}{cc} 1 & 3 \\ 2 & 4 \end{array} \right) \left( \begin{array}{cc} 4 & -2 \\ -3 & 1 \end{array} \right) + 2 \left( \begin{array}{cc} 1 & 2 \\ 2 & 1 \end{array} \right) = \left( \begin{array}{cc} -3 & 5 \\ 0 & 2 \end{array} \right) $


In [5]:
from numpy import array,dot, sqrt

a = array([[1,3],[2,4]],int)
b = array([[4,-2],[-3,1]],int)
c = array([[1,2],[2,1]],int)

print ((dot(a,b)+2*c))


[[-3  5]
 [ 0  2]]

podemos mapear funções em arrays como foi feito com listas

alguns cuidados devem ser tomados pois funções usuais como max, min len não dão resultados esperados quando aplicados em arrays multidimensionais


In [16]:
from numpy import array

a = array([[1,3],[2,4]],int)

print a.size


4

Mas numpy contem funções específicas para essas tarefas com arrays


In [26]:
import numpy as np      # repare na outra forma de importar o numpy!

a = array([[1,3],[2,4]],int)

print a.size            # imprime o tamanho de a
print a.shape           # imprime a forma de a
print '\n'
print np.max(a)         # imprime o valor maximo em a
print np.mean(a)        # imprime a média dos elementos de a


4
(2, 2)


4
2.5

Exercício

faça um programa para calcular a média geométrica de um conjunto de n valores

$\bar{x}=\left[\displaystyle\prod_{i=1}^{n} x_i\right]^{1/n}$ ou $\bar{x} = exp \left( \frac{1}{n} \displaystyle\sum_{i=1}^{n} ln (x_i) \right)$

Observe o programa abaixo:


In [17]:
from numpy import array
a = array([1,1],int)
b = 2*a
print a[0] == b[0]
a[0] = 3
print a
print b


False
[3 1]
[2 2]

observe que no caso de arrays quando fazemos b = a isso não cria uma nova cópia de a! Isso é feito para economizar memória em situações com muitos arrays de grande numero de elementos.

Para criar uma cópia o programa deveria ser:


In [7]:
from numpy import array, copy
a = array([1,1],int)
b = copy(a)
a[0] = 2
print a
print b


[2 1]
[1 1]

Com listas e arrays podemos fazer cortes


In [5]:
r = [1,3,5,7,9,11,13,15]
s = r[2:5]
print s


[5, 7, 9]

repare que o corte consiste em pegar os elementos 2, 3, 4

Isso porque a indexação começa em 0


In [7]:
r = [0,1,2,3,4,5,6,7,8,9]
print r[2:5]
print r[:5]      # imprime todos os elementos até mas não incluindo 5


[2, 3, 4]
[0, 1, 2, 3, 4]

In [ ]:
import numpy as np