Python 3 transforma o intervalo em uma lista

178

Estou tentando fazer uma lista com números 1-1000. Obviamente, isso seria chato de escrever / ler, então estou tentando fazer uma lista com um intervalo. No Python 2, parece que:

some_list = range(1,1000)

teria funcionado, mas no Python 3 o intervalo é semelhante ao xrangedo Python 2?

Alguém pode fornecer algumas dicas sobre isso?

Boathouse
fonte
1
Além disso, some_list[i] == i+1você provavelmente não precisará de uma lista.
Njzk2
1
@RikPoggi. por exemplo, pode ser necessário fornecer uma lista para uma função de plotagem. Às vezes, um intervalo é suficiente, mas um intervalo não pode ser concatenado (é imutável); portanto, se você precisar adicionar um valor inicial padrão a todas as listas que estão sendo plotadas, isso também precisará ser transformado em uma lista.
precisa saber é o seguinte

Respostas:

223

Você pode apenas construir uma lista a partir do objeto range:

my_list = list(range(1, 1001))

É assim que você faz isso com geradores em python2.x também. Normalmente, você provavelmente não precisa de uma lista, já que pode obter o valor de my_list[i]mais eficientemente ( i + 1) e, se precisar iterar, pode apenas voltar atrás range.

Observe também que no python2.x, xrangeainda é indexável 1 . Isso significa que rangeno python3.x também tem a mesma propriedade 2

1print xrange(30)[12] funciona para python2.x

2 A declaração análoga a 1 no python3.x é print(range(30)[12])e também funciona.

mgilson
fonte
4
Este é definitivamente o caminho a percorrer, mas um nitpick: este não é realmente um "elenco"
jterrace
@jterrace mudou "cast" para "convert". Você está certo sobre não ser um elenco ... Eu realmente não sei como chamá-lo exatamente.
mgilson
2
Eu diria "construir" ou "construir" (ou possivelmente "materializar") - como você não está "convertendo" (como tal) um gerador em uma lista, você está criando um novo objeto de lista a partir de uma fonte de dados que acontece para ser um gerador de ... (mas suponho cabelos apenas dividir e não 100% de certeza que sou a favor de qualquer maneira)
Jon Clements
2
Meu +1 para "construir", pois é consistente com outros idiomas OO. Em list(arg)outras línguas, entende-se como chamar um construtor da listclasse. Na verdade, também é o caso do Python. Os debates sobre se o objeto é preenchido durante a construção (como no caso de C ++) ou apenas durante o primeiro método chamado automaticamente (como no __init__()método Python ) não podem alterar a idéia abstrata básica. Minha opinião é que o construtor da lista pega o iterador e preenche a lista com os valores retornados .
pepr 14/07/12
2
Por que ocorre um erro no notebook jupyter e funciona bem no shell? Erro:'range' object is not callable
subtleseeker
34

Em Pythons <= 3.4, você pode, como outros sugeriram, usar list(range(10))para criar uma lista fora de um intervalo (em geral, qualquer iterável).

Outra alternativa, introduzida no Python 3.5com suas generalizações de descompactação, é usando *em uma lista literal []:

>>> r = range(10)
>>> l = [*r]
>>> print(l)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Embora isso seja equivalente list(r), é uma sintaxe literal e o fato de nenhuma chamada de função estar envolvida permite executar mais rapidamente. Também tem menos caracteres, se você precisar codificar golf :-)

Dimitris Fasarakis Hilliard
fonte
4
Para ficar claro, você ainda pode usar uma linha: [*range(10)]funciona bem quando você não precisa do rangeobjetivo para qualquer finalidade, além de inicializar o list. Nota lateral: Minha parte favorita (ok, na verdade não) das generalizações descompactadas é que os sets vazios agora têm uma sintaxe literal {*()}, ou, como eu chamo, o operador de macaco caolho. ;-)
ShadowRanger
@ShadowRanger é assim que eu originalmente pensava em escrevê-lo. Decidi ser um pouco mais detalhado, a fim de não confundir os novos usuários de Python :-)
Dimitris Fasarakis Hilliard
26

no Python 3.x, a range()função tem seu próprio tipo. portanto, neste caso, você deve usar o iterador

list(range(1000))

nurulhudamustaqim
fonte
11
"neste caso, você deve usar o iterador"? O que diabos isso quer dizer?
User2357112 suporta Monica
2
Eu estou usando python 3.7 e tentou x = list (range (1000)), mas tem o TypeError erro: 'list' objeto não é exigível
Earthshaker
@Earthshaker Você deve ter um erro de digitação, comolist(range(1000))()
wjandrea
17

A razão pela qual o Python3 não possui uma função para obter diretamente uma lista variada é porque o designer original do Python3 era bastante novato no Python2. Ele considerou apenas o uso da range()função em um loop for, portanto, a lista nunca precisa ser expandida. De fato, muitas vezes precisamos usar a range()função para produzir uma lista e passar para uma função.

Portanto, nesse caso, o Python3 é menos conveniente quando comparado ao Python2, porque:

  • No Python2, temos xrange()e range();
  • No Python3, temos range()elist(range())

No entanto, você ainda pode usar a expansão da lista desta maneira:

[*range(N)]
xuancong84
fonte
3
O ponto principal é tornar menos conveniente fazer um list, porque geralmente é a coisa errada a fazer. Para 99 de 100 casos de uso, fazendo um real listé ineficiente e sem sentido, uma vez que rangeem si funciona como uma seqüência imutável em quase todos os sentidos, às vezes de forma mais eficiente para boot (por exemplo contenção testes para ints são O(1), vs. O(n)para lists). No Python 2, as pessoas costumavam usar rangepor padrão, embora xrangequase sempre fosse a melhor opção; no Python 3, você pode ativar explicitamente o list, não obtê-lo por acidente usando o nome errado.
ShadowRanger
7
O comentário sobre o designer do Python 3 e sua experiência no Python 2 é bastante ousado e impertinente.
kazarey
@kazarey Mas é verdade? Existem muitas coisas em python que são questionáveis ​​nesse sentido
javadba
1
Voto a favor, especialmente para a descompactação-taquigrafia da lista, mas concordo com @kazarey. O comentário sobre o designer é infundado (ou pelo menos não apoiado por referências) e desnecessário.
Nubarke
12

Você realmente não precisa usar os números de 1 a 1000 em uma lista. Mas se, por algum motivo, você realmente precisar desses números, poderá:

[i for i in range(1, 1001)]

Listar Compreensão em poucas palavras:

A compreensão da lista acima se traduz em:

nums = []
for i in range(1, 1001):
    nums.append(i)

Esta é apenas a sintaxe de compreensão da lista, embora a partir da 2.x. Eu sei que isso funcionará no python 3, mas não tenho certeza se também há uma sintaxe atualizada

O intervalo inicia inclusive o primeiro parâmetro; mas termina em Até, sem incluir o segundo parâmetro (quando fornecidos 2 parâmetros; se o primeiro parâmetro for deixado de fora, ele começará em '0')

range(start, end+1)
[start, start+1, .., end]
inspectorG4dget
fonte
20
Por que compreensão? Apenas:list(range(1000))
Rik Poggi
Obrigado! Você se importaria de explicar por que é eu para eu entrar ... em vez de simplesmente para eu entrar?
Boathouse
Eu não trabalhei com python3. Portanto, não estou totalmente certo sobre como isso funciona. Eu sei que a compreensão funcionará, mas não foi 100% no elenco. Mas se a transmissão funcionar, você está certo e seu caminho é mais pitônico.
inspectorG4dget
1
@ inspectorG4dget: Não é "casting", está chamando o list()construtor com uma iterável . O list()construtor sabe como criar uma nova lista quando recebe qualquer objeto iterável.
22812 Greg Hewgill
4
@ inspectorG4dget: list(range(1000))vai trabalhar em python3 assim como list(xrange(1000))em python2
Rik Poggi
4

Na verdade, se você quiser 1-1000 (inclusive), use a range(...)função com os parâmetros 1 e 1001:, range(1, 1001)porque a range(start, end)função vai do início ao (final de 1), inclusive.

CosmicComputer
fonte
0

Use o intervalo no Python 3.

Aqui está um exemplo de função que retorna entre números de dois números

def get_between_numbers(a, b):
    """
    This function will return in between numbers from two numbers.
    :param a:
    :param b:
    :return:
    """
    x = []
    if b < a:
        x.extend(range(b, a))
        x.append(a)
    else:
        x.extend(range(a, b))
        x.append(b)

    return x

Resultado

print(get_between_numbers(5, 9))
print(get_between_numbers(9, 5))

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]
Rajiv Sharma
fonte
Isso parece estar respondendo a uma pergunta diferente ...?
wjandrea
-1

De fato, esta é uma retro-graduação do Python3 em comparação com o Python2. Certamente, Python2, que usa range () e xrange (), é mais conveniente que Python3, que usa list (range ()) e range (), respectivamente. O motivo é que o designer original do Python3 não é muito experiente; eles consideraram o uso da função range por muitos iniciantes para iterar um grande número de elementos nos quais a memória e a CPU são ineficientes; mas negligenciaram o uso da função range para produzir uma lista de números. Agora, é tarde demais para eles voltarem.

Se eu fosse o designer do Python3, irei:

  1. use irange para retornar um iterador de sequência
  2. use lrange para retornar uma lista de sequências
  3. use range para retornar um iterador de sequência (se o número de elementos for grande, por exemplo, range (9999999) ou uma lista de sequências (se o número de elementos for pequeno, por exemplo, range (10))

Isso deve ser o ideal.

xuancong84
fonte
Como isso responde à pergunta?
wjandrea
Sim, ele responde à pergunta solicitando que os desenvolvedores do Python3 alterem e melhorem o Python3. Mas é improvável que eles mudem, pois não são tão elegantes.
xuancong84