12 votes

Quelle est la manière simple de fusionner des tuples nommés en Python ?

Je veux fusionner deux tuples nommés sans perdre les noms des clés. Si je fais simplement une fusion avec l'opérateur '+', j'obtiens un tuple comme résultat mais sans les noms.

Par exemple :

n [1]: from collections import namedtuple

In [2]: A = namedtuple("A", "a b c")

In [4]: B = namedtuple("B", "d e")

In [5]: a = A(10, 20, 30)

In [6]: b = B(40, 50)

In [7]: a + b
Out[7]: (10, 20, 30, 40, 50)

Comme vous pouvez le voir dans le cas ci-dessus, le résultat de a + b n'est associé à aucun nom.

Mais j'y arrive en créant un troisième tuple nommé, qui contient les champs de A et B.

In [8]: C = namedtuple("C", A._fields + B._fields)

In [9]: C(*(a + b))
Out[9]: C(a=10, b=20, c=30, d=40, e=50)

Est-ce la bonne méthode ou existe-t-il une meilleure façon de procéder ?

8voto

Simeon Visser Points 30697

Quelques observations :

  • En général, Python ne sait pas quoi faire lorsque vous essayez de fusionner deux tuples nommés dont les champs portent le même nom. C'est peut-être la raison pour laquelle il n'existe pas d'opérateur ou de fonction pour cela.

  • El la documentation de _fields dit :

Tuple de chaînes de caractères énumérant les noms des champs. Utile pour l'introspection et pour créer de nouveaux types de tuple nommés à partir de tuples nommés existants.

Cela suggère que votre approche est correcte et peut-être même suggérée par les auteurs du code namedtuple.

8voto

John Crawford Points 1526

Vous avez pratiquement tout compris en ce qui concerne le Python classique, mais vous pouvez simplifier davantage les choses si vous utilisez Python 3.5+.

>>> from collections import namedtuple
>>> A = namedtuple("A", "a b c")
>>> B = namedtuple("B", "d e")
>>> a = A(10, 20, 30)
>>> b = B(40, 50)
>>> C = namedtuple("C", A._fields + B._fields)
>>> C(*(a + b))
C(a=10, b=20, c=30, d=40, e=50)
>>> #Available in Python 3.5+
>>> C(*a, *b)
C(a=10, b=20, c=30, d=40, e=50)

Voici également une fonction que vous pouvez utiliser pour éliminer le code passe-partout si vous le faites fréquemment :

>>> from functools import reduce
>>> from itertools import chain
>>> from operator import add
>>> def namedtuplemerge(*args):
...     cls = namedtuple('_'.join(arg.__class__.__name__ for arg in args), reduce(add, (arg._fields for arg in args)))
...     return cls(*chain(*args))
...
>>> namedtuplemerge(a, b)
A_B(a=10, b=20, c=30, d=40, e=50)

4voto

clacke Points 1534

Python ne créera pas automatiquement un nouveau fichier namedtuple une nouvelle classe. Vous devrez définir la combinaison namedtuple vous-même :

A = namedtuple("A", "a b c")
B = namedtuple("B", "d e")
AB = namedtuple("AB", "a b c d e")

a = A(1,2,3)
b = B(4,5)
ab = AB(*(a+b))

>>> a
A(a=1, b=2, c=3)
>>> b
B(d=4, e=5)
>>> ab
AB(a=1, b=2, c=3, d=4, e=5)

-4voto

lsheng Points 1877

Que diriez-vous de faire

>>> [a] + [b]
[A(a=10, b=20, c=30), B(d=40, e=50)]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X