Jump to content
downloader

[Ajuda] Passar valores de lista para matriz

Recommended Posts

downloader

Tenho qui um problema em passar os valores de um lista para uma matriz :wallbash:

Como estou a trabalhar com python á pouco tempo dai precisar de uma mãozinha nesta situação que para alguém pode ser um erro estupido de se corrigir.

x=[4, 4, 3, 4, 4, 4, 2, 3, 4, 4, 4, 1, 4, 4, 5, 2]


q=[0,3,4,6,0,0,0,9,0,7,5,1,3,1,0,0,1,8,1,7,6,6,5,20]
matrix=[[0]*5]*20
uu=0
vv=-1
xx=0
for p in q:
    vv+=1
    if vv==x[xx]:
        uu+=1
        vv=vv-(x[xx]-1)
        matrix[uu][vv]=p
        xx+=1
    else:
        matrix[uu][vv]=p
print matrix

O que pretendo é os valores de "q" entrem ordenadamente na matriz que criei com "0" que tem uma largura de 5 colunas e que no caso decidi que tivesse 20 linhas.

Mas eu não quero que os valores sejam escritos ordenadamente na matriz. Eu quero que por linha só sejam escritos o numero de valores que estão em "x".

Ou seja a primerira linha é contituida pelos primeiros "4" valores de "q", a segunda pelos seguintes "4" valores, a terceira pelos "3" vaslores seguintes....e por ai fora

A matriz que deveria ficra deveria ser mais ou menos a seguinte:

    [0,3,4,6,0]

    [0,0,0,9,0]

    [0,7,5,0,0]

    [1,2,3,1,0]

    [.....

   

    O meu raciocio foi que fosse á lista "q" e pegasse na primeira posição e coluca-se inicialmente na primeira posição da matriz e ir incrementando só a posição, e quando "vv" (variavel da posição da coluna) fosse igual á primeira posição de x, ou seja x[0] , a variavel uu (variavel da linha) incrementa-se 1 e a variavel da coluna decrementava o valor da posição de "Q" menos 1 para que volta-se a zero.

    Em cada ciclo claro subtituia na matriz e a comparação ia ser feita com o próximo valor da lista x.

    Só que não está a dar os resultados esperados

    Alguem me pode ajudar

    Peço desculpa se não estou a explicar o metodo corretamente. ;)

Share this post


Link to post
Share on other sites
Pedro C.

Se bem percebi o teu problema este código deverá servir:

import numpy as np
x=[4, 4, 3, 4, 4, 4, 2, 3, 4, 4, 4, 1, 4, 4, 5, 2]
q=[0,3,4,6,0,0,0,9,0,7,5,1,3,1,0,0,1,8,1,7,6,6,5,20]
matrix=np.zeros((20,5))
i=0
counter=0
while i < x.__len__():
    j=0
    while j < x[i]:
        if counter < q.__len__():
            matrix[i][j]=q[counter]
            counter=counter+1
        j=j+1
    i=i+1
print matrix

Repara que deixei de usar lista para passar a usar uma matriz numpy. Fiz isto porque são matrizes optimizadas para tratamento númerico (muito ao estilo matlab se conheces a linguagem). É de facto possível fazer isto em lista mas ao experimentar o teu código reparei que estava a atribuir os mesmos valores a todas as linhas da matriz. Deverá ter qualquer coisa a ver com a maneira como a definiste. De qualquer maneira o resultado do código acima foi este:

[[  0.   3.   4.   6.   0.]
[  0.   0.   0.   9.   0.]
[  0.   7.   5.   0.   0.]
[  1.   3.   1.   0.   0.]
[  0.   1.   8.   1.   0.]
[  7.   6.   6.   5.   0.]
[ 20.   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.]]

Share this post


Link to post
Share on other sites
Smoon

Um dos problemas que tens no teu código é na criação da matriz:

não podes criar a matriz desse modo devido a uma característica do python, pois vê o que acontece:

matrix=[[0]*5]*20
matrix[0][0]=1
matrix

assim as tuas linhas ficam todas repetidas:

>>> matrix

[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]

porque na segunda vez que usas a operação *, aquilo repete várias vezes a mesma lista (por referência) e quando mudas um elemento num lado muda também no outro.

uma alternativa seria por ex:

l=20                 #numero de linhas
c=5                  #numero do colunas
matrix=[[0]*c for i in range(l)]

isto é uma escrita compacta que faz o mesmo que:

l=20                 #numero de linhas
c=5                  #numero do colunas
matrix=[]
for i in range(l):
matrix.append([0]*c)

isto é para o caso de quereres utilizar uma matriz baseada nas listas normais de Python.

Ou então podes escolher usar a função zeros(...) da biblioteca numpy como te foi sugerido antes:

matrix=np.zeros((20,5))

Se usares a matriz com as listas normais de python, sem o numpy, além de não precisares do módulo adicional podes ter qualquer tipo de elementos (strings, inteiros, floats, etc....).

Com a matriz do numpy só podes ter números, e o processamento de operações algébricas sobre as matrizes com esse módulo é efectivamente muito mais rápido, mas tu não fazes operações desse género nesse código.

De qualquer modo, ainda tens que rever o que se passa com o teu método de escrita dos valores para a matriz dentro do ciclo. Sugiro que faças essa parte como o Pedro C. te indicou pois o modo dele funciona bem e é claro.

Já agora, não entendi a ideia de usar o:

x.__len__()

pois pelo menos até à versão 2.7 de python tem-se o:

len(x)

que faz o mesmo e é de mais agradável leitura, não é?

Share this post


Link to post
Share on other sites
Pedro C.
Já agora, não entendi a ideia de usar o:

x.__len__()

pois pelo menos até à versão 2.7 de python tem-se o:

len(x)

que faz o mesmo e é de mais agradável leitura, não é?

Era o único comando que conhecia para saber o tamanho de uma lista. Não estava a tentar tentar complicar o código nem nada do género. Mas claro, existindo uma função para fazer isso, faz o código mais legível e provavelmente a função até será mais estável que o método. O len(x) será melhor escolha que o x.__len__(), portanto...

Share this post


Link to post
Share on other sites
downloader

Caro Pedro C. e Smoon antes de mais obrigado pela vossa ajuda.

De facto esta tarde cheguei ás mesmas conclusões que vocês em relação á matriz. Na verdade o que estava a fazer era a criar uma lista de listas, com as listas sempre repetidas.

Só não postei isso antes por falta de tempo.

Assim sendo decidi refazer o meu código.

import numpy

x=[4, 4, 3, 4, 4, 4, 2, 3, 4, 4, 4, 1, 4, 4, 5, 2]
q=[0,3,4,6,0,0,0,9,0,7,5,1,3,1,0,0,1,8,1,7,6,6,5,20...........]
m=-1
uu=0
matrix=numpy.array([[0]*5]*20)
for n in x:
   
   for i in range(0,n):
      m+=1
      
      matrix[uu][i]=q[m]
      
   
   uu+=1
   i=0


print matrix

O resultado é semelhante ao do Pedro C.

[[ 0  3  4  6  0]
[ 0  0  0  9  0]
[ 0  7  5  0  0]
[ 1  3  1  0  0]
[ 0  1  8  1  0]
[ 7  6  6  5  0]
[20  0  0  0  0]
.......................
......................
]

O novo código que criei ainda tem o problema de não ter em atenção os tamanhos das listas, como o Pedro C. teve na sua resolução. Mas como quero aplicar este bocado de código noutra situação em que a lista "x" é extremamente muito mais pequena que "q" não há problema.

No entanto a resolução do Pedro C. é de facto a ideal.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.