6
votes

Utiliser des tuples Python comme des vecteurs

Je dois représenter des vecteurs immuables dans Python ("vecteurs" comme dans l'algèbre linéaire, pas comme dans la programmation). Le tuple semble être un choix évident.

Le problème est que je dois mettre en œuvre des choses comme l'ajout et la multiplication scalaire. Si A code> et B code> sont des vecteurs et c code> est un nombre, le meilleur que je peux penser est ceci: p>

tuple(map(lambda x,y: x + y, a, b)) # add vectors 'a' and 'b'
tuple(map(lambda x: x * c, a))      # multiply vector 'a' by scalar 'c'


1 commentaires

"Sans parler d'éviter l'appel à tuple, puisque la carte renvoie une liste". Vous pouvez éviter le coût de la création d'une liste temporaire en remplaçant la carte avec iTerTools.imap, qui renvoie un itérateur. Je crois que dans la carte Python 3.x retournera toujours un itérateur.


7 Réponses :


0
votes

Depuis à peu près toutes les fonctions de manipulation de séquence, c'est à peu près ce que vous allez avoir à faire.


0 commentaires

3
votes

Pourquoi ne pas créer votre propre classe, faisant appel à 2 variables de membres du point cartésiennes? (Désolé si la syntaxe est un peu éteinte, mon python est rouillé) xxx


3 commentaires

Principalement pour éviter la réinvention des roues; Il y a suffisamment d'utilisations pour l'algèbre linéaire qu'elle ne semble pas probablement que je dois rouler le mien.


@Etaoin vous réinventez déjà la roue si vous essayez d'utiliser vos propres tuples au lieu d'utiliser une classe de vecteur créée par quelqu'un d'autre. :RÉ


J'espère que cela ne vous dérange pas, j'ai réparé cette syntaxe pour vous (au profit des futurs lecteurs)



9
votes

numpy prend en charge diverses opérations algébriques avec ses tableaux.


1 commentaires

+1 pour NUMPY. Les tableaux de NUMPY ont probablement déjà 95% de ce que vous voulez. Il est impossible d'essayer de ré-implémenter des bibliothèques bien connues et de longue date.



11
votes

types immuables sont assez rares dans des extensions de python et de tiers de celui-ci; Le PO affirme à juste titre "Il y a suffisamment d'utilisations pour l'algèbre linéaire qu'elle ne semble pas probablement que je dois rouler le mien" - mais tous les types existants que je sais que l'algèbre linéaire est mutable ! Ainsi, comme l'OP est admis sur l'immuabilité, il n'y a que rien pour cela, mais le rouleau-votre propre itinéraire.

Pas qu'il y ait beaucoup de roulement impliqué, par ex. Si vous avez spécifiquement besoin de vecteurs 2-D: xxx

i "a jeté gratuitement" quelques extras tels que .x et . y Propriétés R / O, une belle représentation à chaîne, une convivialité dans des ensembles ou des clés dans les dicts (pourquoi d'autre voudrait-on avoir une immuabilité? -), une empreinte de mémoire faible, ABS (V) à donner v de la longueur de vecteur - Je suis sûr que vous pouvez penser à d'autres méthodes "ce ne serait pas-cool-si" si "des opérateurs, en fonction de votre champ d'application, et ils" ll sera tout aussi facile. Si vous avez besoin d'autres dimensionnalités, ce ne sera pas beaucoup plus difficile, bien qu'un TAD moins lisible depuis le .x , .y notation ne s'applique plus ;-) ( Mais j'utiliserais Genexps, pas mappe ).


1 commentaires

+1 pour le suivi! Je veux une solution n-dimensionnelle (et on dirait que je vais probablement aller avec Numpy et repenser la mutabilité) mais cela vaut la peine d'être réfléchie.



8
votes

En héritant de Tuple, vous pouvez faire une belle classe de vecteur assez facilement. Voici assez de code pour fournir un ajout de vecteurs et la multiplication d'un vecteur d'un scalaire. Il vous donne des vecteurs de longueur arbitraire et peut travailler avec des nombres complexes, des INT ou des flotteurs.

class Vector(tuple):
    def __add__(self, a):
        # TODO: check lengths are compatable.
        return Vector(x + y for x, y in zip(self, a))
    def __mul__(self, c):
        return Vector(x * c for x in self)
    def __rmul__(self, c):
        return Vector(c * x for x in self)

a = Vector((1, 2, 3))
b = Vector((2, 3, 4))

print a + b
print 3 * a
print a * 3


0 commentaires

7
votes

Bien que l'utilisation d'une bibliothèque comme numpy semble être la résolution de l'OP, je pense qu'il existe encore une certaine valeur dans une solution simple qui ne nécessite pas de bibliothèques supplémentaires et que vous pouvez rester immuables, avec Itérables.

Utilisation de la ITERTOOLS CODE> et Opérateurs CODE> MODULES: P>

(11, 22, 33)


2 commentaires

Je travaille avec Python3 dans un raspberrypi zéro et je reçois importerror: impossible d'importer le nom 'imap'


J'ai corrigé le code de la réponse: Pour Python 3, utilisez la carte au lieu de IMAP.



2
votes

Pour une utilisation occasionnelle, une solution Python 3 sans répétition de Lambdas est possible via à l'aide de l'emballage de l'opérateur standard: xxx pré>

qui imprime: p>

[5 7 9]
[ 4 10 18]


0 commentaires