Extraction d'une liste sous Jinja 2?

Bonjour,

J’aurais besoin d’aide avec Jinja2, dans une liste lorsque je récupère certaines value qui sont en double dans la liste cela me les sors en double sauf que j’aimerais qu’elles sortent qu’une seule fois ?

Pourriez-vous m’aider s’il vous plait ?

Par avance je vous remercie de votre aide et bonne journée.

Ma configuration


Voici le code :

{% set wordcounter = 0 %}
{{ list }}
{% for lines in list %}
  {{ lines }}
  {% for key,value in lines.items() %}
    {% if key== "idx" %}
      {% if value == "pol" %}
        **** {{ wordcounter }}
        {% if wordcounter == 0 %}
          {{ [lines.group](http://lines.group/)}}
          {% set wordcounter = wordcounter + 1 %}
          {{ wordcounter }}
        {% endif %}
      {% endif %}
    {% endif %}
  {% endfor %}
{% endfor %}

Voici la liste :

list:

  • { idx: pol, group: group1, user: user1 }
  • { idx: pol, group: group1, user: user1b }
  • { idx: mec, group: group2, user: user2 }
  • { idx: mec, group: group2, user: user2b }

Salut,

Voilà un exemple… plus simple

EDIT : Attention à la mise en forme, c’est pas vraiment lisible tes valeurs. Je corrige

Merci beaucoup,
Ce n’est pas possible de garder la même mise en forme que mon code de base ?
Afin d’avoir différentes « key » contenant des « values » et si au final il y a deux values identiques, à la fin cela montre que seul value au lieu de deux ?

Sans plus d’info sur le contexte c’est pas simple. Ton code mélange à la fois la transformation et la mise en forme.
Et comme tu le dis, ne fais pas ce que tu veux …

Par ailleurs ton exemple est pas vraiment explicite:

  • List ressemble à un json malformé
  • Lu ligne par ligne, il n’a pas de doublon.
  • Tu fais un IF sur ‹ idx › => toutes les lignes en contiennent
  • Tu filtre sur ‹ pol ›, pourquoi pas direct un IF sur ‹ pol › ?
  • group et user ça sert à un moment ?
  • Il me manque ce que tu attends comme liste brute à la fin, avant de faire ton http://
  • Map/Key, ok mais sur quels items et pourquoi ? Juste pour l’itération, je vois pas le besoin…

Du coup, à relire c’est pas évident quand on est pas dedans… Et donc proposer un truc à partir de ça c’est risqué.

En fait, mon objectif est que dans une liste avec des key et des value, le code récupére les valeurs désirées et si elles sont en double il les affiche que une fois.

Par exemple :

list:

{ name: pol, group: group1, user: user1 }
{ name: pol, group: group1, user: user1b }
{ name: mec, group: group2, user: user2 }
{ name: mec, group: group2, user: user2b }

Dans la liste ci dessus, j’aimerais récupérer dans les lignes uniquement avec pol dans la catégorie name. Dans les lignes correspondantes(pol), désormais j’aimerais récupère les groupes (group 1) dans la catégorie « group: »

Et ensuite afficher les deux groupes soit deux fois group1 sauf que au lieu de l’avoir en deux fois j’aimerais l’avoir d’afficher qu’en une fois vu que ça fait un doublon.

J’essaie d’être le plus explicite possible :slightly_smiling_face:

Donc je synthètise parce que c’est pas forcement plus clair pour moi:
Tu as ça au départ ?

Et pas ça

[
  { "name": "pol", "group": "group1", "user": "user1" },
  { "name": "pol", "group": "group1", "user": "user1b" },
  { "name": "mec", "group": "group2", "user": "user2" },
  { "name": "mec", "group": "group2", "user": "user2b" }
]

Les données viennent déjà d’un truc à toi non ? C’est pas une chaine, c’est pas un json…C’est bizarre en tout cas

Et à la fin tu veux ça ?
{ name: pol, group: group1, user: user1 }
ou ça ?
group: group1
ou ça ?
group1

Ma liste est complète celle-ci

Et mon but final c’est d’avoir :
group1

Et éventuellement par la suite :

group1 group4

Séparé par un espace, bien sûr si la liste est plus grande

Donc faire simple !

Voilà l’exemple pas à pas

{## Imitate available variables: ##}
{% set my_test_json = [
  { "name": "pol", "group": "group1", "user": "user1" },
  { "name": "pol", "group": "group1", "user": "user1b" },
  { "name": "mec", "group": "group2", "user": "user2" },
  { "name": "mec", "group": "group2", "user": "user2b" }
] %}

my_test_json is {{ my_test_json }}

pol is {{ my_test_json | selectattr('name','equalto', 'pol') |list }}

group is  {{ my_test_json | selectattr('name','equalto', 'pol') | map(attribute='group') |list }}

group unique is  {{ my_test_json | selectattr('name','equalto', 'pol') | map(attribute='group') |unique|list }}

Merci je vais tester,

Je dirais que mon code d’origine ressemble plus à cela, et la problématique c’est que ça ressort deux fois le group1

{% for lines in list %}
{% for key,value in lines.items() %}
{% if key == "name" %}
{% if value == "pol" %}
{{lines.group}}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}

list:

{ "name": "pol", "group": "group1", "user": "user1" }
{ "name": "pol", "group": "group1", "user": "user1b" }
{ "name": "mec", "group": "group2", "user": "user2" }
{ "name": "mec", "group": "group2", "user": "user2b" }

Tu as du json (ou pas loin) comme type de données en entrée, c’est un format de données structuré qui se manipule facilement. Revenir à utiliser des itérrations/boucles et la manipulations de ligne, c’est ne pas profiter de toutes les fonctions du json. C’est encore plus vrai quand on code en Jinja, car json c’est un format très bien pris en compte.

J’utilise du jinja2 pour Ansible :slight_smile:
Et souhaite tester sur https://j2live.ttl255.com/

HA fait ça très bien aussi… Outils de développement => Modèles
Et c’est 100% compatible HA surtout

Que signifie le sigl HA s’il vous plaît?

HA = Home Assistant

En fait, je viens de tester, j’aimerais garder le même code que j’ai ci-dessous mais ne pas avoir de doublon ci-dessous.

{% for lines in list %}
{% for key,value in lines.items() %}
{% if key == "name" %}
{% if value == "pol" %}
{{ lines.group }}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}

list:

- { name: "pol", group: "group1", user: "user1" }
- { name: "pol", group: "group1", user: "user1b" }
- { name: "mec", group: "group2", user: "user2" }
- { name: "mec", group: "group2", user: "user2b" }

J’ai testé de rajouter le paramètre « unique » après lines.group à la ligne 5 mais il n’est pas pris en compte visiblement.

Mon objectif est d’avoir une seul fois group1 à la fin, avez-vous une idée s’il vous plait en gardant la même structure.


C’est quoi la raison d’une telle contrainte ?
De mon côté quitte à expliquer les bases du codage en Jinja, je préfère autant montrer les bons concepts plutôt que de proposer une rustine : c’est ni formateur sur le moment, ni bénéfique à long terme. En utilisant des moyens compliqués, on arrive jamais à avoir du code efficace, simple à maintenir et à savoir facilement relire après coup

En fait, l’architecture système derrière sera en Jinja2 basé sur du Ansible d’où mon code.
Mon objectif est simplement que les résultats sortent en une seule fois s’il y a des doublons :slight_smile:

Techniquement ça ne réponds pas à la question…

L’exemple proposé :

  • est en Jinja2
  • est compatible Ansible
  • et élimine les doublons

Quand il s’agira de manipuler les playbooks d’ansible, un code leger sera un atout

Merci beaucoup, existe t-il un moyen pour que le résultat sorte en brut sans les apostrophe et les crochet ?

Effectivement le code est beaucoup plus propre et compréhensible avec Ansible sans utiliser les boucles de Jinja dans mon code d’origine.

En reprenant ce code propre, est-ce possible également de rajouter un « ou » ‹ mec › afin d’obtenir par exemple le group1 et le group2.

{{ list | selectattr('name','equalto', 'pol' or 'mec') | map(attribute="group") | unique | list }}

Si je comprends bien le « code propre » est codé en Jinja mais via Ansible ? Alors que mon code d’origine c’est du pur Jinja ? J’ai du mal à faire la différence réelle entre les deux

Il faut revoir les bases je pense et notamment les structures de données … Ici, les crochets et les quotes sont purement fonctionnelles… Il s’agit de la représentation d’un tableau avec 1 élement de type chaine de caractère…

L’exercice est différent … Mettre un OU ça impose que la liste des cas soit finie : donc que 2 cas possibles pol ou mec
Plus malin à faire c’est de peut-être se dire qu’on se fiche des valeurs name et qu’on veut uniquement celles des groupe. Comme ça s’il existe un jour une 3ème valeur, ça marchera directement

Les 2 sont du jinja… Jinja fonctionne avec n’importe quel interpréteur Jinja donc potentiellement HA ou ansible…