2010-06-20 6 views
1

J'ai un morceau de code qui va prendre une chaîne et la répéter de telle sorte que la longueur de la chaîne soit x.Optimisation: Répétition de chaîne Python

>>> import math 
>>> def repeat(data, length): 
     return (data * int(math.ceil(float(length)/len(data))))[:length] 
>>> repeat("Hello World", 22) 
'Hello WorldHello World' 
>>> repeat("Hello World", 20) 
'Hello WorldHello Wor' 

Y a-t-il un moyen de l'optimiser? J'ai besoin que cette opération soit rapide, car elle sera beaucoup utilisée. Notez que cela doit également fonctionner avec les listes.

+0

Je me demandais juste. Avez-vous confirmé que 'repeat (" Hello World ", 22)' est plus rapide que "Hello World" * 22' – Wolph

+0

@WoLpH: Il résout un problème légèrement différent. Il veut que "Hello World" (ou n'importe quelle chaîne) soit répété autant de fois que nécessaire, mais ne dépasse pas N caractères de longueur. Pas la même chose que 'string * n'. –

+0

@Brian: en effet, dans ce cas, ma question est invalide :) Je ne vois aucune option d'optimisation beaucoup plus loin. Simplement l'évaluation comparative devrait suffire. – Wolph

Répondre

3

Cela pourrait être légèrement plus rapide:

def repeat(string, length): 
    L = len(string) 
    return string * (length // L) + string[:length % L] 

je dis « pourrait » parce que beaucoup dépend de la string typique et length! Avec 'Hello World' et 61, j'ai chronométré ceci (sur un vieux Mac portable) à 1 microsecondes contre 1.66 microsecondes pour le vôtre; avec 'Hello World'*100 et 61*123, 2,08 microsecondes contre 2,68 pour la vôtre. Juste comment rapide vous avez besoin, sur quelle longueur chaînes, et pour quelles valeurs typiques de length? " // est de" diviser par troncature "(juste pour s'assurer que cela fonctionne en Python 3 et Python 2 ;-) même si Stack Overflow colorie des choses comme s'il s'agissait d'un commentaire (comme en C++).

+0

Cela accélère quelque peu, il va falloir être assez bon. Merci! – skeggse

+0

@CMC, de rien! –

0

Il n'est pas nécessaire de faire un virgule flottante ici; dans les anciennes versions de Python, dites simplement "int (length)/len (string)", et dans les nouvelles versions, vous pouvez utiliser l'opérateur "//". Lorsque vous obtenez le résultat, vous pouvez simplement ajouter 1 pour vous assurer que c'est assez long. Ou, au prix de quelques additions supplémentaires, vous pouvez être plus précis et ne jamais faire la chaîne initiale trop long:

... 
    return (data * ((int(length) + len(data) - 1)/len(data)))[:length] 
0

Au lieu de int(math.ceil(float(length)/len(data))) vous pouvez simplement utiliser length/len(data) + 1. Ce n'est pas exactement la même chose, mais ça devrait marcher aussi.

Et avant d'essayer de le faire plus rapidement, êtes-vous sûr que cette fonction est un goulot d'étranglement? Combien de milliers de fois appellerez-vous chaque seconde?

Pour savoir quelle variante d'une fonction est la plus rapide que vous devriez la profiler, le module timeit est généralement utile.

0

Si vous voulez vraiment optimiser, vous devez réécrire votre fonction en C comme une extension pour python.

Vous pouvez trouver des informations here. Désolé pour mon anglais, je suis nouveau dans ce domaine.

+0

Je dois le garder en python, même si "Python" et "speed" ne vont pas vraiment bien ensemble. – skeggse