2010-07-30 6 views
3

Pouvez-vous décrire la différence entre deux modes de concaténation de chaînes: opérateur __add__ simple et modèles %s? J'ai eu quelques recherches dans cette question et trouvé %s (sous forme sans utiliser de parenthèses) un peu plus vite.Chaîne de concaténation en Python

Une autre question est apparue: pourquoi le résultat de 'hell%s' % 'o' fait référence à une autre région de mémoire que 'hell%s' % ('o',)?

Il y a un exemple de code:

l = ['hello', 'hell' + 'o', 'hell%s' % 'o', 'hell%s' % ('o',)] 
print [id(s) for s in l] 

Résultat:

[34375618400, 34375618400, 34375618400, 34375626256] 

post-scriptum Je connais l'internalisation de chaînes :)

+0

Je pense que vous devriez le tester avec des variables, je soupçonne que ces utilisations simples pourraient être optimisées au stade de la compilation; je suppose que la forme '% s' est toujours plus lente si le motif est une chaîne variable – UncleZeiv

Répondre

7

Voici un petit exercice:

>>> def f1(): 
    'hello' 


>>> def f2(): 
    'hel' 'lo' 


>>> def f3(): 
    'hel' + 'lo' 


>>> def f4(): 
    'hel%s' % 'lo' 


>>> def f5(): 
    'hel%s' % ('lo',) 


>>> for f in (f1, f2, f3, f4, f5): 
    print(f.__name__) 
    dis.dis(f) 


f1 
    1   0 LOAD_CONST    1 (None) 
       3 RETURN_VALUE   
f2 
    1   0 LOAD_CONST    1 (None) 
       3 RETURN_VALUE   
f3 
    2   0 LOAD_CONST    3 ('hello') 
       3 POP_TOP    
       4 LOAD_CONST    0 (None) 
       7 RETURN_VALUE   
f4 
    2   0 LOAD_CONST    3 ('hello') 
       3 POP_TOP    
       4 LOAD_CONST    0 (None) 
       7 RETURN_VALUE   
f5 
    2   0 LOAD_CONST    1 ('hel%s') 
       3 LOAD_CONST    3 (('lo',)) 
       6 BINARY_MODULO   
       7 POP_TOP    
       8 LOAD_CONST    0 (None) 
      11 RETURN_VALUE   

Comme vous pouvez le voir, toutes simples concaténations/mise en forme sont effectuées par le compilateur. La dernière fonction nécessite une mise en forme plus complexe et donc, je suppose, est réellement exécutée. Depuis tous ces objets créés au moment de la compilation, ils ont tous le même identifiant.

+0

Donc, si je tape du code dans la console Python, il est compilé cela interprété? –

+0

@Roman: oui. Pas très différent de la façon dont vous exécuteriez un fichier .py. – SilentGhost

1

L'utilisation de % est, techniquement parlant, la chaîne formatant, pas de concaténation. Ce sont deux mondes entièrement différents. Si vous connaissez l'internement de chaîne, sachez qu'il n'y a absolument aucune garantie que deux chaînes occuperont la même mémoire qu'une autre. Le fait que dans votre exemple les trois premiers ne soit rien de plus qu'une pure coïncidence. Je ne suis pas sûr à 100% comment la mise en forme de chaîne fonctionne, mais je sais qu'il n'est pas implémenté la même chose dans le C sous-jacent que la concaténation - je pense que cela fonctionne un peu plus sur le modèle ''.join(sequence), qui est également plus rapide que + pour les grandes chaînes - voir this post pour plus d'informations.

* en quelque sorte.

+0

Ok, ce n'est pas une concaténation, mais utilisé de la même manière et retourne presque le même résultat. –

+0

essentiellement, oui. La concaténation de chaînes ne doit être utilisée que pour des chaînes plus petites et seulement quelques fois (après environ 7 concaténation, il est beaucoup plus rapide d'utiliser ''' .join()') –