Lorsque j'itère les valeurs de list1 de start à stop, comme dans:

for value in list1[start:stop]:
    ....

Est-ce que python copie d'abord cette partie de la liste (comme cela se fait en faisant list2 = list1[:])? Cela pourrait devenir très coûteux pour les grandes listes!

S'il ne le copie pas dans l'exemple ci-dessus, est-ce toujours vrai? Je dois faire le type de boucle suivant, très souvent, sur de grandes sections de (très) grandes listes:

for index, value in enumerate(list1[start:stop], start):
    ....
6
Jeff 21 déc. 2011 à 17:46

3 réponses

Meilleure réponse

list1[start:stop] crée une nouvelle liste, point. C'est toujours le cas, que vous itériez directement sur le résultat ou que vous ayez une fonction entre les deux ou que vous l'utilisiez dans un autre contexte (vous auriez besoin d'un langage modérément statique ou d'une inférence de type sophistiquée pour optimiser même pour les simples instances du premier cas).

Notez que cela est indépendant de l'itération ! L'itération elle-même n'est pas copiée et la liste des tranches de copie même si vous jetez le résultat.

Il ne copie que des pointeurs, donc si vous prenez toujours de très petites sous-listes, vous ne remarquerez probablement aucune différence. Si les sous-listes sont plus grandes, vous pouvez soit parcourir les indices ([x]range) soit utiliser itertools.islice. Cependant, ce dernier devrait d'abord ignorer start éléments, vous pouvez donc payer une lourde pénalité pour les économies de mémoire. Le premier est laid, mais le plus efficace asymptomiquement .

8
21 déc. 2011 à 13:58

Oui.

L'expression list1[start:stop] crée une nouvelle liste contenant les éléments dans la plage spécifiée. Cependant, il ne copie pas les données réelles, juste un tas de pointeurs, donc à moins que la liste ne soit très longue, les frais généraux n'auront normalement pas d'importance.

2
Duncan 21 déc. 2011 à 13:51

Au lieu de poser cette question, vous auriez pu simplement tester cela avec la méthode d'identification magique

>>> x=[1,2,3,4]
>>> id(x[1])   
4971620
>>> id(x[1:][0]) #same as the original list
4971620
>>> id(x[2:3])
44327400
>>> id(x)
44408224
>>> 

x[2:3] crée en fait une nouvelle liste, mais les éléments sont toujours référés à la liste d'origine.

1
Abhijit 21 déc. 2011 à 13:52
8590781