Python 3 tourner la plage dans une liste

178

J'essaie de faire une liste avec des chiffres 1-1000. De toute évidence, ce serait ennuyeux à écrire / lire, donc j'essaie de faire une liste avec une plage. Dans Python 2, il semble que:

some_list = range(1,1000)

aurait fonctionné, mais en Python 3, la plage est similaire à celle xrangede Python 2?

Quelqu'un peut-il donner un aperçu de cela?

Boathouse
la source
1
aussi, some_list[i] == i+1donc vous n'avez probablement pas vraiment besoin d'une liste de toute façon.
njzk2
1
@RikPoggi. par exemple, il peut être nécessaire de fournir une liste pour une fonction de traçage. Parfois, une plage suffit, mais une plage ne peut pas être concaténée (est immuable), donc si vous devez ajouter une valeur de départ par défaut à toutes les listes tracées, celle-ci doit également être transformée en liste.
SherylHohman

Réponses:

223

Vous pouvez simplement construire une liste à partir de l'objet range:

my_list = list(range(1, 1001))

C'est ainsi que vous le faites avec les générateurs de python2.x également. En règle générale, vous n'avez probablement pas besoin d'une liste puisque vous pouvez trouver la valeur de my_list[i]plus efficacement ( i + 1), et si vous avez juste besoin d'itérer dessus, vous pouvez simplement vous rabattre sur range.

Notez également que sur python2.x, xrangeest toujours indexable 1 . Cela signifie que rangesur python3.x a également la même propriété 2

1print xrange(30)[12] fonctionne pour python2.x

2 L'instruction analogue à 1 dans python3.x est print(range(30)[12])et cela fonctionne aussi.

mgilson
la source
4
C'est certainement la voie à suivre, mais un pinaillage: ce n'est pas vraiment un "casting"
jterrace
@jterrace a changé "cast" en "convert". Vous avez raison de ne pas être un casting ... Je ne sais pas vraiment comment l'appeler exactement.
mgilson
2
Je dirais "construire" ou "construire" (ou éventuellement "matérialiser") - comme vous ne "convertissez" pas (en tant que tel) un générateur en liste, vous créez un nouvel objet de liste à partir d'une source de données, ce qui se produit être un générateur ... (mais s'pose juste de fendre les cheveux et pas sûr à 100% de ce que je préfère quand même)
Jon Clements
2
Mon +1 pour "construire" car il est cohérent avec d'autres langages OO. Le list(arg)est compris dans d'autres langages comme appelant un constructeur de la listclasse. En fait, c'est aussi le cas Python. Les débats pour savoir si l'objet est rempli pendant la construction (comme dans le cas C ++) ou seulement pendant la première méthode appelée automatiquement (comme dans la __init__()méthode Python ) ne peuvent pas changer l'idée abstraite de base. Mon point de vue est que le constructeur de liste prend l'itérateur et remplit la liste avec les valeurs renvoyées .
pepr le
2
Pourquoi cela donne-t-il une erreur dans le notebook jupyter et fonctionne bien dans shell? Erreur:'range' object is not callable
subtleseeker
34

Dans Pythons <= 3.4, vous pouvez, comme d'autres l'ont suggéré, utiliser list(range(10))pour créer une liste à partir d'une plage (en général, toute itération).

Une autre alternative, introduite dans Python 3.5avec ses généralisations de décompression, consiste à utiliser *dans un littéral de liste []:

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

Bien que cela soit équivalent à list(r), c'est une syntaxe littérale et le fait qu'aucun appel de fonction n'est impliqué lui permet de s'exécuter plus rapidement. C'est aussi moins de caractères, si vous avez besoin de coder le golf :-)

Dimitris Fasarakis Hilliard
la source
4
Pour être clair, vous pouvez toujours le faire sur une seule ligne: [*range(10)]fonctionne très bien lorsque vous n'avez pas besoin de le rangepour un autre but que l'initialisation du list. Note latérale: Ma partie préférée (d'accord, pas vraiment) des généralisations de déballage est que les sets vides ont maintenant une syntaxe littérale {*()}, ou comme je l'appelle, l'opérateur du singe borgne. ;-)
ShadowRanger
@ShadowRanger c'est comme ça que j'ai pensé à l'origine de l'écrire. J'ai décidé d'être un peu plus verbeux pour ne pas confondre les nouveaux utilisateurs de Python :-)
Dimitris Fasarakis Hilliard
26

dans Python 3.x, la range()fonction a son propre type. donc dans ce cas, vous devez utiliser iterator

list(range(1000))

nurulhudamustaqim
la source
11
"dans ce cas, vous devez utiliser l'itérateur"? Qu'est-ce que ça veut dire?
user2357112 prend en charge Monica
2
J'utilise python 3.7 et j'ai essayé x = list (range (1000)) mais j'ai l'erreur TypeError: l'objet 'list' n'est pas appelable
Earthshaker
@Earthshaker Vous devez avoir une faute de frappe, commelist(range(1000))()
wjandrea
17

La raison pour laquelle Python3 n'a pas de fonction pour obtenir directement une liste à distance est que le concepteur original de Python3 était assez novice en Python2. Il n'a considéré que l'utilisation de la range()fonction dans une boucle for, ainsi, la liste ne devrait jamais avoir besoin d'être développée. En fait, très souvent, nous devons utiliser la range()fonction pour produire une liste et passer dans une fonction.

Par conséquent, dans ce cas, Python3 est moins pratique que Python2 car:

  • En Python2, nous avons xrange()et range();
  • En Python3, nous avons range()etlist(range())

Néanmoins, vous pouvez toujours utiliser l'extension de liste de cette manière:

[*range(N)]
xuancong84
la source
3
Le but est de rendre moins pratique la création d'un list, car ce n'est généralement pas la bonne chose à faire. Pour 99 cas d'utilisation sur 100, créer un réel listest inefficace et inutile, car rangeelle-même agit comme une séquence immuable de presque toutes les manières, parfois plus efficacement pour démarrer (par exemple, les tests de confinement pour ints sont O(1), contre O(n)pour lists). Dans Python 2, les gens avaient tendance à utiliser rangepar défaut, même si xrangec'était presque toujours la meilleure option; dans Python 3, vous pouvez activer explicitement le list, ne pas l'obtenir par accident en utilisant le mauvais nom.
ShadowRanger
7
Le commentaire sur le concepteur de Python 3 et son expertise en Python 2 est assez audacieux et impertinent.
kazarey
@kazarey Mais est-ce vrai? Il y a beaucoup de choses en python qui sont discutables dans ce sens
javadba
1
Je voterais pour, en particulier pour le raccourci de déballage pour construire la liste, mais je suis d'accord avec @kazarey. Le commentaire sur le concepteur est à la fois sans fondement (ou du moins, sans référence) et inutile.
Nubarke
12

Vous ne devriez vraiment pas avoir besoin d'utiliser les nombres 1 à 1 000 dans une liste. Mais si pour une raison quelconque vous avez vraiment besoin de ces chiffres, vous pouvez faire:

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

Compréhension de la liste en quelques mots:

La compréhension de la liste ci-dessus se traduit par:

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

Ceci est juste la syntaxe de compréhension de liste, bien qu'à partir de 2.x. Je sais que cela fonctionnera dans python 3, mais je ne suis pas sûr qu'il existe également une syntaxe mise à niveau

La plage commence avec le premier paramètre; mais se termine jusqu'à, sans inclure le deuxième paramètre (lorsqu'il est fourni 2 paramètres; si le premier paramètre est laissé désactivé, il commencera à '0')

range(start, end+1)
[start, start+1, .., end]
inspecteurG4dget
la source
20
Pourquoi comprendre? Juste:list(range(1000))
Rik Poggi
Merci! Pourriez-vous expliquer pourquoi c'est i for i in ... au lieu de simplement for i in?
Boathouse le
Je n'ai pas travaillé avec python3. Je ne suis donc pas tout à fait sûr de son fonctionnement. Je sais que la compréhension fonctionnera, mais ce n'était pas à 100% sur le casting. Mais si le casting fonctionne, alors vous avez raison et votre chemin est plus pythonique.
inspectorG4dget
1
@ inspectorG4dget: Ce n'est pas du "casting", il appelle le list()constructeur avec un itérable . Le list()constructeur sait comment créer une nouvelle liste lorsqu'on lui attribue un objet itérable.
Greg Hewgill
4
@ inspectorG4dget: list(range(1000))fonctionnera en python3 comme list(xrange(1000))en python2
Rik Poggi
4

En fait, si vous voulez 1-1000 (inclus), utilisez la range(...)fonction avec les paramètres 1 et 1001:, range(1, 1001)car la range(start, end)fonction va du début à (fin-1), inclus.

CosmiqueOrdinateur
la source
0

Utilisez Range dans Python 3.

Voici un exemple de fonction qui renvoie entre les nombres de deux nombres

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

Résultat

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

[5, 6, 7, 8, 9]  
[5, 6, 7, 8, 9]
Rajiv Sharma
la source
Cela semble répondre à une autre question ...?
wjandrea
-1

En fait, il s'agit d'une rétro-gradation de Python3 par rapport à Python2. Certes, Python2 qui utilise range () et xrange () est plus pratique que Python3 qui utilise respectivement list (range ()) et range (). La raison en est que le concepteur original de Python3 n'est pas très expérimenté, ils ont uniquement considéré l'utilisation de la fonction range par de nombreux débutants pour itérer sur un grand nombre d'éléments où la mémoire et le processeur sont à la fois inefficaces; mais ils ont négligé l'utilisation de la fonction de plage pour produire une liste de nombres. Maintenant, il est trop tard pour eux de revenir déjà.

Si je devais être le concepteur de Python3, je:

  1. utiliser irange pour renvoyer un itérateur de séquence
  2. utilisez lrange pour renvoyer une liste de séquences
  3. utiliser range pour renvoyer soit un itérateur de séquence (si le nombre d'éléments est grand, par exemple, range (9999999), soit une liste de séquences (si le nombre d'éléments est petit, par exemple, range (10))

Cela devrait être optimal.

xuancong84
la source
Comment cela répond-il à la question?
wjandrea
Oui, cela répond à la question en demandant aux développeurs Python3 de changer et d'améliorer Python3. Mais il est peu probable qu'ils changent car ils ne sont pas si élégants.
xuancong84