Pergunta

Eu tenho uma série de Python Tuples representando coordenadas:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]

Eu quero criar a lista a seguir:

l = []
for t in tuples:
  l[ t[0] ][ t[1] ] = something

Eu recebo um IndexError:. Index lista fora da faixa

Minha formação é em PHP e eu esperava que, em Python você pode criar listas que começam com índice> 0, lacunas ou seja, marca e, em seguida, preenchê-los, mas parece que você não pode.

A idéia é fazer com que as listas ordenadas depois. Eu sei que posso fazer isso com um dicionário, mas tanto quanto eu sei dicionários não podem ser classificados por chaves. Atualizar :. Agora eu sei que eles podem - ver a solução aceita

Edit: O que eu quero fazer é criar uma matriz 2D que irá representar a matriz descrita com as coordenadas tupla, então iterar-lo em ordem. Se eu usar um dicionário, eu não tenho nenhuma garantia de que a iteração sobre as chaves será em ordem -> (0,0) (0,1) (0,2) (1,0) (1,1) (1,2 ) (2,0) (2,1) (2,2)

alguém pode ajudar?

Foi útil?

Solução

O que quer dizer exatamente por "mas, tanto quanto eu sei dicionários não podem ser classificados por chaves"?

Enquanto isso não é rigorosamente o mesmo que um "dicionário ordenado", você pode facilmente transformar um dicionário em uma lista, classificado pela chave, o que parece ser o que você está depois:

>>> tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
>>> l = {}
>>> for t in tuples:
...    l[t] = "something"
>>> sorted(l) # equivalent to sorted(l.keys())
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)]
>>> sorted(l.items()) # make a list of (key, value) tuples, and sort by key
[((0, 0), 'something'), ((0, 1), 'something'), ((1, 0), 'something'), ((1, 1), 'something'), ((2, 1), 'something')]    

(Virei something para a string "algo" apenas para fazer o trabalho de código)

Para fazer uso deste para o seu caso, no entanto (se eu entendi corretamente, que é), você ainda precisa preencher o dicionário com os valores Nenhum ou algo para cada "esvaziar" coordenar tuple)

Outras dicas

Não, você não pode criar uma lista com lacunas. Mas você pode criar um dicionário com chaves tupla:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = {}
for t in tuples:
    l[t] = something

Update: Tentar usar NumPy , ele fornece ampla gama de operações sobre as matrizes e matriz. Cite de pfd livre no NumPy disponível no site (3.4.3 Plano Iterator indexação): "Como mencionado anteriormente, X.flat retorna um iterador que irá iterar sobre toda a matriz (em estilo C-contígua com o último índice variando o mais rápido ". parece com o que você precisa.

Você deve olhar para dicts para algo como isso.

for t in tuples:
  if not l.has_key(t[0]):
    l[t[0]] = {}
  l[t[0]][t[1]] = something

iteração sobre o dict é um pouco diferente do que a iteração sobre uma lista, no entanto. Você vai ter as chaves (), valores () e itens () para ajudar com isso.

EDIT: tentar algo como isto para encomenda:

for x in sorted(l.keys()):
   for y in sorted(l[x].keys()):
       print l[x][y]

Você cria um unidimensional l lista e quiser usá-lo como uma lista bidimensional. É por isso que você receber um erro de índice.

Você tem as seguintes opções: criar um mapa e usar a tupla t como índice:

l = {}
l[t] = something

e você terá entradas em l como:

{(1, 1): something}

Se você quer uma estrutura de matriz tradicional vou aconselhá-lo a olhar para numpy . Com numpy você começa matrizes n-dimensionais com indexação "tradicional".

Como mencionei uso numpy,

com numpy você pode criar uma matriz de 2 dimensões, cheio de zeros ou uns ou ... Tha você pode preencher qualquer valor desejado com indexação [x, y] como você deseja. Claro que você pode interagir sobre linhas e colunas ou todo o conjunto como uma lista.

Se você sabe o tamanho que você antes da mão, você pode fazer uma lista de listas como esta

>>> x = 3
>>> y = 3
>>> l = [[None] * x for i in range(y)]
>>> l
[[None, None, None], [None, None, None], [None, None, None]]

O que você pode então iterate como você inicialmente sugerido.

Estendendo a resposta Nathan 's,

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
x = max(tuples, key = lambda z : z[0])[0] + 1
y = max(tuples, key = lambda z : z[1])[1] + 1
l = [[None] * y for i in range(x)]

E então você pode fazer o que quiser

Como mencionado anteriormente, você não pode fazer listas com lacunas e dicionários podem ser a melhor escolha aqui. O truque é garante que l[t[0]] existe quando você coloca algo na posição t[1]. Para isso, eu usaria um defaultdict .

import collections
tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = collections.defaultdict(dict)
for t in tuples:
    l[t[0]][t[1]] = something

Desde l é um defaultdict, se l[t[0]] não existe, ele irá criar um dict vazio para você colocar o seu something em na posição t[1].

Nota: isso acaba sendo a mesma resposta da @ unwesen, sem a menor tédio de mão-verificação de existência do dict interior. Isso se deve a resposta simultânea.

As soluções de dicionários dadas são provavelmente melhor para a maioria dos propósitos. Para o seu problema de iteração sobre as chaves em ordem, geralmente você faria em vez iterate sobre o espaço de coordenadas , não as chaves de dicionários, exatamente da mesma maneira que você tem para sua lista de listas. Use .get e você pode especificar o valor padrão de uso para as células em branco, ou, alternativamente, usar "collections.defaultdict" para definir um padrão no momento da criação dict. por exemplo.

for y in range(10):
    for x in range(10):
        value = mydict.get((x,y), some_default_value)
        # or just "value = mydict[x,y]" if used defaultdict

Se você precisa fazer uma lista real de listas, você pode construí-lo diretamente como abaixo:

max_x, max_y = map(max, zip(*tuples))
l=[[something if (x,y) in tuples else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

Se a lista de tuplas é provável que seja longo, o por motivos de desempenho, você pode querer usar um conjunto para a pesquisa, como executa "(x,y) in tuples" uma varredura da lista, ao invés de uma pesquisa rápida por hash. ou seja, altere a segunda linha para:

tuple_set = set(tuples)
l=[[something if (x,y) in tuple_set else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

Eu acho que você só ter declarado uma lista dimensional.

Eu acho que você declará-lo como

l = [][]

Editar : Isso é um erro de sintaxe

>>> l = [][]
  File "<stdin>", line 1
    l = [][]
           ^
SyntaxError: invalid syntax
>>> 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top