Pergunta

Eu sei que uma lista de compreensão vai fazer isso, mas eu queria saber se existe uma ainda mais curta (e mais Pythonic?) abordagem.

Eu quero criar uma série de listas, todos de comprimento variável.Cada lista irá conter o mesmo elemento e, repetido n vezes (onde n = comprimento da lista).Como faço para criar as listas, sem fazer

[e for number in xrange(n)]

para cada lista?

Foi útil?

Solução

Você também pode escrever:

[e] * n

Você deve observar que, se E for, por exemplo, uma lista vazia, você obtém uma lista com n referências à mesma lista, não n listas vazias independentes.

Teste de performance

À primeira vista parece Essa repetição é a maneira mais rápida de criar uma lista com n elementos idênticos:

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

Mas espere - não é um teste justo ...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

A função itertools.repeat Na verdade, não cria a lista, apenas cria um objeto que pode ser usado para criar uma lista, se desejar! Vamos tentar isso de novo, mas convertendo para uma lista:

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

Então, se você quiser uma lista, use [e] * n. Se você quiser gerar os elementos preguiçosamente, use repeat.

Outras dicas

>>> [5] * 4
[5, 5, 5, 5]

Tenha cuidado quando o item que está sendo repetido é uma lista. A lista não será clonada: todos os elementos se referirão à mesma lista!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

Criar uma Lista de Item Único Repetido n Vezes em Python

Imutável itens

Para imutáveis itens, como Nenhum, strings, tuplas, ou frozensets, você pode fazê-lo assim:

[e] * 4

Note que este é o melhor utilizados apenas com imutáveis itens (strings, tuplas, frozensets ) na lista, porque todos eles apontam para o mesmo item no mesmo local na memória.Eu uso frequentemente, quando eu tenho que construir uma tabela com um esquema de todas as cadeias, de modo que eu não tenho para dar um mapeamento um para um.

schema = ['string'] * len(columns)

Mutável itens

Eu usei Python por um longo tempo agora, e eu nunca vi um caso de uso, onde eu iria fazer o acima com uma mutáveis instância.Em vez disso, para se obter, digamos, uma mutáveis lista vazia, definir, ou dict, você deve fazer algo como isto:

list_of_lists = [[] for _ in columns]

O sublinhado é simplesmente um desperdício nome da variável, neste contexto.

Se você tiver apenas o número, que seria:

list_of_lists = [[] for _ in range(4)]

O _ não é nada de especial, mas a sua codificação ambiente verificador de estilo provavelmente vai reclamar se você não pretende usar a variável e usar qualquer outro nome.


Advertências para usar o imutável método com mutável itens:

Cuidado com fazer isso com objetos mutáveis, quando você alterar um deles, todos eles mudar porque eles são todos mesmo objeto:

foo = [[]] *4
foo[0].append('x')

foo agora retorna:

[['x'], ['x'], ['x'], ['x']]

Mas com objetos imutáveis, você pode fazê-lo funcionar porque você alterar a referência, não o objeto:

>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]

>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]

Mas, novamente, objetos mutáveis, não são boas para isso, porque no local de operações de alterar o objeto, e não a referência:

l = [set()] * 4
>>> l[0] |= set('abc')    
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]

ITERTOOLS tem uma função apenas para isso:

import itertools
it = itertools.repeat(e,n)

É claro itertools Dá a você um iterador em vez de uma lista. [e] * n dá uma lista, mas, dependendo do que você fará com essas seqüências, o itertools A variante pode ser muito mais eficiente.

Como outros apontaram, o uso do operador * para um objeto mutável duplica as referências; portanto, se você alterar um, alterá -las todas. Se você deseja criar instâncias independentes de um objeto mutável, sua sintaxe xRange é a maneira mais pitônica de fazer isso. Se você se incomoda em ter uma variável nomeada que nunca é usada, pode usar a variável anônima sublinheira.

[e for _ in xrange(n)]
[e] * n

Deveria trabalhar

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top