8
votes

Python: tuples de longueur variable

[Python 3.1]

Je suis en train de suivre le concept de conception que les tuples doivent être de longueur connue (voir Ce commentaire ) et les tuples de longueur inconnus doivent être remplacés par des listes dans la plupart des cas. Ma question est dans quelles circonstances devrais-je me dévier de cette règle?

Par exemple, je comprends que les tuples sont plus rapides de créer à partir de la chaîne et des littéraux numériques que des listes (voir Un autre commentaire ). Donc, si j'ai du code critique de la performance où il existe de nombreux calculs tels que sumproducteur (tuple1, tuple2) , dois-je les redéfinir pour travailler sur des listes malgré une performance frappée? ( sumproducteur ((x, y, z), (a, b, c)) est défini comme x * a + y * b + z * c , et son Les arguments ont des longueurs non spécifiées mais égales).

Et qu'en est-il du tuple qui est automatiquement construit par Python lors de l'utilisation de def f (* x) ? Je suppose que ce n'est pas quelque chose que je devrais coercer à énumérer à chaque fois que je l'utilise.

BTW, est (x, y, z) plus rapide à créer que [x, y, z] (pour les variables plutôt que les littéraux)?


0 commentaires

5 Réponses :


0
votes

tuple est beaucoup plus simple de type, puis liste. Utilisez-les partout où vous pouvez vivre avec eux étant immobile.


0 commentaires

3
votes

J'utilise toujours la plus grande structure de données appropriée pour le travail et ne vous inquiétez pas vraiment si un tuple me sauverait une demi-milliseconde ici ou là. Pré-obscusant votre code ne paient généralement pas à la fin. Si le code est trop lent, vous pouvez toujours le profiler plus tard et modifier le code .01% du code où il compte vraiment.

Tout ce dont vous parlez sont liés à la mise en œuvre de la version Python et du matériel en cours d'exécution. Vous pouvez toujours faire ces choses à voir ce qu'elle serait sur votre machine.

Un exemple commun de ceci est que les «vieilles chaînes immuables sont lentes à concaténer» dans Python. C'était vrai il y a environ 10 ans, puis ils ont modifié la mise en œuvre en 2.4 ou 2.5. Si vous effectuez vos propres tests, ils fonctionnent maintenant plus rapidement que les listes, mais les gens sont convaincus aujourd'hui et utilisent des constructions stupides qui ont réellement ralentissé!


2 commentaires

Peut-être devriez-vous faire du profil avant de dire que les autres n'ont pas. Essayez de construire des tuples et des listes à partir de littéraux numériques et de chaînes dans le temps et voyez ce qui se passe. En outre, quelle est tout ce genre de choses sur le python obscurci? Comment une tuple est-elle obscurcissante quelque chose? Semble parfaitement clair pour moi.


Si vous utilisez des tuples lorsque le code aurait été plus clair avec des listes, il vient d'obscucher le code. Un tuple en soi peut être clair à quiconque, mais il s'agit d'un bloc de code plus important. Lire la réponse de Batcheler NED. Si vous avez besoin d'une utilisation. Si vous avez besoin de l'autre utilisation. Un tuple et une liste sont construits dans "Temps constant" O (1). Alors, ça vaut la peine de compromettre la conception pour une petite vitesse?



14
votes

Dans mon esprit, la seule distinction intéressante entre les tuples et les listes est que les listes sont mutables et que les tuples ne sont pas. Les autres distinctions que les gens mentionnent semblent complètement artificiels pour moi: les tuples sont comme des structures et des listes sont comme des tableaux (c'est là que les «tuples doivent être une longueur connue» provient). Mais comment la structure est-elle alignée sur l'immuabilité? Ce n'est pas le cas.

La seule distinction qui compte est la distinction que la langue fait: mutabilité. Si vous devez modifier l'objet, utilisez définitivement une liste. Si vous avez besoin de hachage, l'objet (comme une clé dans une dicte ou un élément d'un ensemble), vous en avez besoin pour être immuable, utilisez donc un tuple. C'est tout.


0 commentaires

2
votes

dans quelles circonstances dois-je écarter de cette [tuples doit être d'une longueur connue] règle?

Aucun.

Il est une question de signifie . Si un objet a un sens en fonction d'un nombre fixe d'éléments, alors il est un tuple. (X, y) des coordonnées, (C, M, Y, K) des couleurs, (lat, lon) la position, etc., etc.

A tuple a un nombre fixe d'éléments sur la base du domaine du problème en général et les spécificités du problème à résoudre.

La conception d'un tuple avec un nombre indéfini d'éléments peu de sens. Lorsque le commutateur-nous de (x, y) à (x, y, z), puis à (x, y, z, w) de coordonnées? Non par concaténer simplement une valeur que si elle est une liste? Si nous passons de 2-d à 3-d coordonnées il y a habituellement quelques jolies maths fantaisie pour cartographier les systèmes de coordonnées. Pas annexant un élément à une liste.

Qu'est-ce que cela signifie pour déplacer les couleurs de (r, g, b) à autre chose? Quelle est la 4ème couleur dans le système rgb? Pour cette question, quelle est la cinquième couleur dans le ststem cmyk?

Tuples ne pas Modifier taille.

* args est un tuple parce qu'il est immuable. Oui, il a un nombre indéfini d'arguments, mais il est un contre-exmaple rare de tuples de tailles connues, définies.


Que faire au sujet d'un tuple de longueur indéfinie. Ce contre-exemple est si profonde que nous avons deux choix.

  1. Rejeter l'idée même que tuples sont de longueur fixe, et contraints par le problème ,. L'idée même de (x, y) les coordonnées et (r, g, b) des couleurs est tout à fait inutile et mal à cause de ce contre-exemple. tuples de longueur fixe? Jamais.

  2. convertir toujours tous les * args pour les listes d'avoir toujours un niveau difficile de conformité irréfléchi à un principe de conception. Cachée aux listes? Toujours.

    J'aime tous ou choix rien, car ils font l'ingénierie logicielle de façon simpliste et irréfléchi.

    Peut-être, dans ces cas de coin, il y a un petit bout de « cela nécessite de penser » ici. Un morceau minuscule.

    Oui, * args est un tuple. Oui, il est d'une longueur indéfinie. Oui, il est un contre-exemple où « fixé par le domaine du problème » est forgées de toutes pièces par « tout simplement immuable ».

    Cela nous amène au troisième choix dans le cas où une séquence est immuable pour une autre raison. Vous ne serez jamais muter, il est donc normal d'être un tuple de taille illimitée. Dans le cas même plus-rare où vous les valeurs de popping * args parce que vous traitez comme une pile ou une file d'attente, alors vous voudrez peut-être faire une liste hors de lui. Mais nous ne pouvons pas pré-résoudre tous les problèmes possibles.

    Parfois Penser est nécessaire.


    Lorsque vous faites la conception, vous concevez un tuple pour une raison. Pour imposer une significative structure sur vos données. Numéro de longueur fixe d'éléments? Tuple. nombre variable d'éléments (à savoir, mutable)? Lister.


11 commentaires

La performance est-elle trop petite pour vous inquiéter? Et que dois-je faire sur les propres tuples indéfinis-longs de Python (lorsque des arguments sont emballés dans un tuple) - dois-je le contraindre à une liste immédiatement?


Je peux penser à au moins un contre-exemple à votre demande. * args . C'est un tuple et je n'ai aucune idée de combien de temps ça va être. Je ne pense pas que vous puissiez créer un contre-exemple plus «pythonique» que cela.


@max: "La performance est-elle trop petite pour s'inquiéter?" Oui. Il s'agit d'environ Signification . La performance n'a pas d'importance dans ce cas. Si vous avez besoin de plus de vitesse, trouvez le bon algorithme. Si vous pouvez prouve Vous avez le bon algorithme et que vous pouvez prouver la mise en œuvre du python est trop lente, passez à C pour cette chose.


@max, "Quand des arguments sont emballés dans un tuple" vous JAMAIS Ajoutez ou modifiez ceci. Depuis que vous JAMAIS Ajoutez ou modifiez, vous n'avez pas besoin de le convertir en liste. Il n'y a pas de sens signification à cela. Vous l'utilisez simplement comme tuple.


Que faites-vous si vous avez un objet d'une taille fixe, mais vous devez modifier ses éléments? Ou si vous avez un objet de taille variable, mais vous devez l'utiliser comme une clé?


@Ned Batchelder: taille fixe mais mutable ... C'est un moment parfait pour créer de nouveaux objets immuables à partir d'objets immuables anciens objets immuables dans le style de programmation fonctionnelle au lieu de la programmation OO. Cela fonctionne vraiment très bien. Et oui, convertir une liste (ou une dict) à un tuple pour le rendre approprié pour une clé dict est un hack impair, mais nécessaire.


Cela ressemble à une simplification excessive ... ;-)


Qu'en est-il de mon exemple avec Sumproduct ? Voulez-vous le voir comme mauvaise conception s'il utilise des tuples (de longueur inconnue, mais immutable)?


@max: Un "sumproducteur" générique n'est pas vraiment approprié. Dans la plupart des applications, vous DO SAVOIR quelle taille vos vecteurs sont et vous devrait Ecrire un sumproducteur qui correspond à la taille réelle de vos vecteurs réels. Vous n'avez pas vraiment besoin de résoudre des problèmes génériques et tout possibles, universel Sumproduct fonction. Vous avez vraiment besoin d'un SumProduct4 pour effectuer des transformations de coordonnées sur les vecteurs (x, y, z, r).


@ S.Lott: Je suis respectueusement en désaccord. J'utilise sumproducteur pour calculer, par exemple, la valeur actuelle d'un portefeuille de stocks, qui est la somme de (quantité (i) * prix (i)) à travers tout stocks i dans le portefeuille. La taille du portefeuille est variable.


@max: Dans ce cas, vous avez une liste pour commencer avec . Pas un vecteur approprié. Veuillez ne pas confondre les vecteurs de longueur fixe de dimensionnalité connue avec des listes de valeurs. Veuillez les garder clairement séparées. Ils ont rien à faire avec les autres. Sauf la coïncidence qu'ils sont à la fois des séquences et - avec des soins - vous pouvez le rendre ambigu. Ce n'est pas intrinsèquement ambigu. Les vecteurs de longueur fixe (c'est-à-dire des tuples) et des listes de longueur arbitraire résolvent différents types de problèmes. Mais peut avoir un comportement de suchauffé, mais il y a essentiellement différent.



1
votes

Dans ce cas, vous devez probablement envisager d'utiliser des tableaux numpus et numpus.

Il y a une convertissage aérienne et des tableaux numpus, mais si vous faites un tas de calcul, il sera beaucoup plus rapide


0 commentaires