IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Liste aleatoire avec des conditions [Python 3.X]


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut Liste aleatoire avec des conditions
    Bonjour à tous,

    Je manque de logique sur la façon de faire une liste bien particulière (ou un tableau si vous avez votre propre idée) :

    En gros j'ai besoin de générer une liste aléatoire mais avec des conditions. Pour l'instant j'ai réussi à faire 3 conditions mais je viens de voir que j'ai une exception que je n'avais pas prévu
    j'ai besoin de : une liste de 5 couples aleatoires (10 nombres) de 20 à 24 dans mon exemple, avec les conditions suivantes :
    1) jamais plus de 2 fois le même nombre dans une liste (ce qui revient à avoir obligatoirement chaque nombre présent 2 fois en tout dans la liste)
    2) jamais deux nombres identiques dans un même couple
    3) ce que je n'arrive pas à faire : jamais deux couples identiques au sein de la liste (si j'ai (20,21), je ne veux pas d'un autre (20,21), ni d'un (21,20)
    De plus le problème qu'il peut arriver c'est que la seule combinaison possible restante soit deux nombres identiques (mais donc impossible et ça boucle en continu)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    couples = []
    i = 0
    while len(couples) < 10:
        couples.append(randrange(20, 25))
        #Si l'alea en cours est égal à sa paire
        if i%2 == 1 and couples[i] == couples[i-1]:
            #le supprimer de la liste
            del couples[i]
            continue
        #Si on arrive au dernier alea et qu'il y a plus de 2 fois le meme nombre
        if i == 9 and couples.count(couples[i])>= 3 :
            #Reinitialiser la liste
            couples = []
            i = 0
            continue
        #A partir du deuxième couple, s'il y a plus de 2 fois le même nombre
        if i >= 2 and couples.count(couples[i])>= 3 :
            #supprimer l'alea en cours
            del couples[i]
            continue
        else:
            i += 1
    Si vous avez une idée et même une façon plus simple et plus propre de faire ça je suis preneur (comparaison de tableau peut etre)
    Merci d'avance.

    Bon week-end.

  2. #2
    Membre éclairé
    Homme Profil pro
    BTS SN IR
    Inscrit en
    Mai 2017
    Messages
    513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : BTS SN IR

    Informations forums :
    Inscription : Mai 2017
    Messages : 513
    Points : 700
    Points
    700
    Par défaut
    Bonjour, je te propose quelques pistes:

    - il faut que tu récupère chaque nombre de ta liste de tuple.
    - génère 2 nombres, c1 et c2 de façon aléatoire.
    - que tu regarde combien de fois c1 est présent dans cette liste, de même pour c2.
    - que tu regarde que le couple (c1, c2) ne soit pas déjà dans ta liste de tuple, de même pour le couple (c2, c1).

    si jamais je te propose ma façon, elle semble faire ce que tu souhaite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    import random
    couples = []
    while len(couples) < 5:
    	# on récupère toutes les valeurs de la variable couples
    	list_nb = []
    	for couple in couples:
    		for nb in couple:
    			list_nb.append(nb)
     
    	c1, c2 = random.randrange(20, 25), random.randrange(20, 25)  # on génère c1 et c2
    	if c1 != c2: #on vérifie qu'ils sont différents
    		if list_nb.count(c1) <2 and list_nb.count(c2) <2: # on que c1 soit moins de 2 fois dans la liste des nombres, de même pour c2
    			if (c1, c2) not in couples and (c2, c1) not in couples:
    				couples.append((c1, c2))
     
    print(couples)
    # [(23, 22), (22, 24), (21, 20), (23, 20), (24, 21)]

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Un autre algorithme est également possible puisque l'on sait que chaque nombre entre 20 et 24 doit être présent exactement 2 fois au final. On démarre de la liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x=[[20, 20], [21, 21], [22, 22], [23, 23], [24, 24]]
    puis on choisit deux nombre i1 et i2 entre 0 et 4, et deux nombres j1 et j2 entre 0 et 1.
    (i1,j1) et (i2,j2) nous donne ainsi des positions dans le tableau, que l'on va pouvoir intervertir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x[i1][j1],x[i2][j2] = x[i2][j2],x[i1][j1]
    On répète cela un nombre arbitraire de fois (mettons 100 fois). A la fin on vérifie que c'est bien mélangé, c'est à dire qu'on répond bien à tous les critères, du style aucun couple identique. Et si ce n'est pas le cas on recommence les interversions jusqu'à ce que les critères soient ok.

    Au lieu de faire 100 fois, on peut aussi ne pas se fixer de nombre d'itération et tester après chaque itération si le mélange est correct et s'arrêté dès qu'il l'est.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut
    Merci de votre aide.
    Je suis sur un truc comme ça :
    (c'est pas mal mais j'ai une erreur à regler je vous tiens au jus)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #!/usr/bin/python
    # -*- coding: latin-1 -*-
     
    from random import randrange
     
    #Le nombre de connexion à un interrupteur par led (2 max)
    led = [0, 0, 0, 0, 0]
    #Tous les couples possible (éliminer les doublons)
    combines = [[1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]]
    #Les couples choisis au hasard par bouton
    button = []
     
     
    def removeCombineContaining(ledIndex):
        i = 0
        for combine in combines:
            #Si la combinaison contient la ledIndex
            if combine[0] == ledIndex or combine[1] == ledIndex:
                #Supprimer l'élément en question
                del combines[i]
     
            i += 1
     
     
     
     
    def couples():
        #Parcours des 5 interrupteurs
        for i in range(0, 5):
            #Choisir un nombre aléatoire entre 0 et la taille du tableau
            index = randrange(0, len(combines)-1)
            #Choisir l'élément choisi à l'index 'index' dans les différentes combinaisons (tmp est une liste de deux)
            tmp = combines[index]
            #Incrémenter les compteurs de connexion pour les 2 leds
            led[tmp[0]-1] += 1
            led[tmp[1]-1] += 1
            #Supprimer l'élément choisi de la liste de toutes les combinaisons
            del combines[index]
            #Si après avoir fait nos petites actions, la led 1 du couple choisi possède 2 connexions
            if led[tmp[0]-1] >= 2:
                #Supprimer les autres combinaisons contenant la led en question
                removeCombineContaining(tmp[0])
            #Si après avoir fait nos petites actions, la led 2 du couple choisi possède 2 connexions
            if led[tmp[1]-1] >= 2:
                #Supprimer les autres combinaisons contenant la led en question
                removeCombineContaining(tmp[1])
            #Une fois toutes les actions terminés, rajouter la combinaison dans le tableau des bouttons
            button.append(tmp)
     
     
    couples()

  5. #5
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Si tu part de l'ensemble des couples possibles, alors dans ce cas tu as juste à mélanger cette liste (cf. random.shuffle) et à prendre ce qu'il te faut dedans dans l'ordre. Comme un jeu de cartes que tu as mélangé et ensuite tu pioches les cartes une à une dans l'ordre.

  6. #6
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut.

    En utilisant comme tu as fait avec les combinaisons possibles et avec une exception.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    import random
    import itertools
     
    mini = 1
    maxi = 5
    nbCombi = 5 # ne peut excéder maxi
     
    sel = []
    combi = list(itertools.combinations(range(mini, maxi + 1), 2))
    choix = combi.copy()
    occur = dict.fromkeys(range(mini, maxi + 1), 0)
    i = 0
     
    while True :
        try :
            s = random.choice(choix)
        except IndexError :
            # Retour arrière sur 2 éléments
            for _ in range(2) :
                occur[sel[-1][0]] -= 1
                occur[sel[-1][1]] -= 1
                combi.append(sel.pop())
                i -= 1
        else :
            sel.append(s)
            i += 1
            if i == nbCombi :
                break
            combi.remove(s)
            occur[s[0]] += 1
            occur[s[1]] += 1
        finally :
            choix = [n for n in combi if occur[n[0]] < 2 and occur[n[1]] < 2]
     
    """
    # Eventuel mélange des valeurs
    ind = [0, 1]
    for i, s in enumerate(sel) :
        random.shuffle(ind)
        sel[i] = (s[ind[0]], s[ind[1]])
    """
     
    print("selection :", sel)
    Il faut gérer le cas où toutes les occurences sont à 2 et une reste à 0, ce qui peut se produire parfois, d'où le retour arrière sur 2 éléments dans l'exception, on peut améliorer encore cela afin d'exclure les tuples ayant posés problèmes en effectuant une trace des éléments ajoutés pour les exclure avant la sélection au hasard, mais cela en vaut-il le coup, à voir.

    En attendant que quelqu'un d'autre propose mieux, ce qui ne saurait tarder ^^
    Le temps ronge l'amour comme l'acide.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut
    merci beaucoup.

    En fait j'ai fini par tourner en rond avec ma fonction de suppression, car deux problèmes se sont posés:
    - lorsque je supprime une entrée de ma liste, la boucle for saute un index sur l’itération suivante.
    - et je me retrouve aussi dans le cas suivant des fois : [1,2],[2,3],[1,3] jusque là ça va ça respecte les critères, et bein non car il me reste deux couples à créer, et la seule possibilité restante est [4,5]

    Je suis donc resté sur mon truc pourri de départ, avec un une succession de "or" pour condition, mais ça marche dans tous les cas et c'est pas plus long que de faire un "truc propre"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    couples = []
    i = 0
    while len(couples) < 10:
        #penser à remplacer ici en reel par 74 à 78
        couples.append(randrange(20, 25))
        #Si i est impaire et qu'il est égal à sa paire
        if i%2 == 1 and couples[i] == couples[i-1]:
            #le supprimer
            del couples[i]
            continue
        #Si on arrive au dernier alea et qu'il y a plus de 2 fois le meme nombre
        if i == 9 and couples.count(couples[i])>= 3 :
            #Reinitialiser la liste
            couples = []
            i = 0
            continue
        #S'il y a deux fois la meme paire, réinitialiser la liste
        if i == 9 :
            #
            liste_tri = []
            liste1 = []
            liste2 = []
            liste3 = []
            liste4 = []
            liste5 = []
            for k in range (0,2):
                liste1.append(couples[k])
                liste2.append(couples[k+2])
                liste3.append(couples[k+4])
                liste4.append(couples[k+6])
                liste5.append(couples[k+8])
            liste1.sort()
            liste2.sort()
            liste3.sort()
            liste4.sort()
            liste5.sort()
            if liste1 == liste2 or liste1 == liste3 or liste1 == liste4 or liste1 == liste5 or liste2 == liste3 or liste2 == liste4 or liste2 == liste5 or liste3 == liste4 or liste3 == liste5 or liste4 == liste5:
                print(liste1,liste2,liste3,liste4,liste5)
                couples = []
                i = 0                
            continue

  8. #8
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par lg_53 Voir le message
    Un autre algorithme est également possible puisque l'on sait que chaque nombre entre 20 et 24 doit être présent exactement 2 fois au final. On démarre de la liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x=[[20, 20], [21, 21], [22, 22], [23, 23], [24, 24]]
    puis on choisit deux nombre i1 et i2 entre 0 et 4, et deux nombres j1 et j2 entre 0 et 1.
    (i1,j1) et (i2,j2) nous donne ainsi des positions dans le tableau, que l'on va pouvoir intervertir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x[i1][j1],x[i2][j2] = x[i2][j2],x[i1][j1]
    On répète cela un nombre arbitraire de fois (mettons 100 fois). A la fin on vérifie que c'est bien mélangé, c'est à dire qu'on répond bien à tous les critères, du style aucun couple identique. Et si ce n'est pas le cas on recommence les interversions jusqu'à ce que les critères soient ok.

    Au lieu de faire 100 fois, on peut aussi ne pas se fixer de nombre d'itération et tester après chaque itération si le mélange est correct et s'arrêté dès qu'il l'est.
    Et qu'est ce qui ne vous plait pas dans la méthode que je vous ai donné là ? Car avec cet algo pas de problème de cas particulier où il faut revenir en arrière 1 voire 2 fois.
    Regardez


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from random import randrange
    from copy import deepcopy
     
    def tirage_valide(liste_de_couple):
        #### Retourne True ou False selon si la liste_de_couple est un tirage valide ou non.
        sort = [ sorted(couple) for couple in liste_de_couple ]
        n=len(liste_de_couple)
        ### Double for imbriqué : plus élégant et générique (ne dépend pas de la longueur de la liste) que :
        ####   if liste1 == liste2 or liste1 == liste3 or liste1 == liste4 or liste1 == liste5 or liste2 == liste3 or liste2 == liste4 or liste2 == liste5 or liste3 == liste4 or liste3 == liste5 or liste4 == liste5:
        for i in range(n):
            ### On teste si chaque élément du couple est bien différent
            if sort[i][0]==sort[i][1] : return False
            ### On teste si le couple n'est pas égal à un autre couple
            for j in range(i+1,n):
                if sort[i]==sort[j] : return False
        return True
     
    def melanger(x):
        y = deepcopy(x) ### Evite de modifier directement le paramètre x passé en entrée de la fonction
        n = len(y)
        while not tirage_valide(y):
            i1,j1 = randrange(0,n), randrange(0,2)
            i2,j2 = randrange(0,n), randrange(0,2)
            ## On interverti les positions (i1,j1) et (i2,j2)
            y[i1][j1],y[i2][j2] = y[i2][j2],y[i1][j1]
        return y
     
    x=[[20, 20], [21, 21], [22, 22], [23, 23], [24, 24]]      
    print(melanger(x))

  9. #9
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    j'y vais de ma proposition également :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import random, itertools
    while True:
       l1 = random.sample(range(20, 25), 5)
       l2 = random.sample(range(20, 25), 5)
       l3 = [{l1[i], l2[i]} for i in range(len(l1))]
       if all([len(i) == 2 for i in l3]):                             # pas de couples avec des valeurs identiques ? ex: (24, 24)
          if len([i for i,j in itertools.groupby(l3)]) == len(l3):    # pas de doublons, même inversés ? ex: {20, 23} == {23, 20}
             break                                                    # alors c'est qu'on a nos listes, on quitte la boucle
    et le résultat pour vérification :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> print(f'l1 = {l1}\nl2 = {l2}\nl3 = {list(zip(l1,l2))}')
    l1 = [23, 20, 22, 24, 21]
    l2 = [20, 22, 21, 23, 24]
    l3 = [(23, 20), (20, 22), (22, 21), (24, 23), (21, 24)]

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut
    Et qu'est ce qui ne vous plait pas dans la méthode que je vous ai donné là ? Car avec cet algo pas de problème de cas particulier où il faut revenir en arrière 1 voire 2 fois.
    Regardez
    lg_53 : Ce n'est pas que ça ne me plait pas ^^, mais j'ai du mal avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    y[i1][j1],y[i2][j2] = y[i2][j2],y[i1][j1]
    Il faut que je regarde bien en détail je te remercie.
    je le teste en rentrant ce soir

    salut,

    Buffer_Bob : j'y vais de ma proposition également :
    C'est très court comme code, c'est pas mal je teste au aussi ce soir.

  11. #11
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par esope60 Voir le message
    lg_53 : Ce n'est pas que ça ne me plait pas ^^, mais j'ai du mal avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    y[i1][j1],y[i2][j2] = y[i2][j2],y[i1][j1]
    Suffit de demander !

    C'est équivalent à ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a= y[i2][j2]
    y[i2][j2] = y[i1][j1]
    y[i1][j1] = a
    Techniquement ici, a n'est là que pour garder en mémoire une valeur dont on a besoin juste pour faire l'échange et dont on a plus besoin après. La formule que je présentait initialement permet de s'affranchir de cette variable intermédiare. Tu peux tester sur des variables plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a=1
    b=2
    a,b = b,a
    print(a)
    print(b)
    équivalent à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a=1
    b=2
     
    c=a ### avant d'effacer a, je dois me rappeler de sa valeur quelque part
    a=b ### je viens d'effacer l'ancienne valeur de a, et je lui ai affecté la valeur de b
    b=c ### je donne à b la valeur c qui ai la sauvegarde de la précédente valeur de a
    #### Je n'ai maintenant plus besoin de c
     
    print(a)
    print(b)

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut
    Alors je dois vraiment être un gros bêta, parce que je ne comprends toujours pas à quoi ça sert.

    J'ai bien compris ce que tu expliques avec la façon dont fonctionne l'inversion, a devient b et b devient a.
    Mais à quoi ça sert dans le code ? Pourquoi on veut intervertir des variables dont on vient d'assigner des valeurs ? J'ai compris le reste du code.

    Cela fonctionne à merveilles en tout cas, je vais prendre l'intégralité et l'insérer dans mon module. Merci beaucoup.


    Buffer_Bob : cela ne fonctionne pas, je me retrouve avec des 20:21 et 21:20, dommage.

  13. #13
    Membre émérite

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Points : 2 328
    Points
    2 328
    Par défaut
    Comment mélanger une liste ? L'une des possibilités est de choisir 2 positions, de les intervertir, et de recommencer autant de fois que l'on veut.

    Là c'est exactement cela. La répétition de l'intervertion permet de mélanger le tableau (Une liste de liste peut être vu comme un tableau, ca facilite les choses lorsqu'on se les représente ainsi)

    Note que l'on aurait pu utiliser des fonctions de mélange déjà présente dans python, comme random.shuffle, mais ca ne traite qu'avec des liste (et pas des liste de listes), donc ca obligerait de partir d'une liste de 10 éléments, la mélanger, et la transformer en tableau 5x2, vérifier si ca convient et si cela ne convient pas repartir de la liste plate pour la remélanger et la retransformer en tableau, etc ... Ca se fait aussi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    from random import shuffle
     
    def liste1D_vers_tab(x):
        y = []
        for i in range(0,len(x),2): ### On va de 2 en 2
            y.append([x[i],x[i+1]])
        return y
     
    ### Note : la fonction précédente peut s'ecrire de manière plus concise en utilisant une "liste en intension"
    #def liste1D_vers_tab(x):
    #    return [ [x[i],x[i+1]] for i in range(0,len(x),2) ]
     
    def melanger2(x):
        y_list=deepcopy(x)
        y_tab = liste1D_vers_tab(y_list)
        while not tirage_valide(y_tab):
            shuffle(y_list)  ### shuffle modifie directement y_list
            y_tab = liste1D_vers_tab(y_list)
        return y_tab
     
    print(melanger2(x))

  14. #14
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par esope60 Voir le message
    Buffer_Bob : cela ne fonctionne pas, je me retrouve avec des 20:21 et 21:20, dommage.
    sur mon py 3.7 ça fonctionne très bien, tests à l'appui, donc je demande à le voir (que ça ne fonctionne pas) pour le croire, mais dans tous les cas si tu as trouvé une solution qui te convient c'est l'essentiel

    edit: au temps pour moi après vérif à l'instant ça ne fonctionne effectivement pas, je me demande encore comment j'ai pu louper une erreur pareille
    celui-ci devrait fonctionner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import random
    while True:
       l1 = random.sample(range(20, 25), 5)
       l2 = random.sample(range(20, 25), 5)
       l3 = [{l1[i], l2[i]} for i in range(len(l1))]
       if all([len(i) == 2 for i in l3]):                    # pas de couples avec des valeurs identiques ? ex: (24, 24)
          if len(set([tuple(i) for i in l3])) == len(l3):    # pas de doublons, même inversés ? ex: {20, 23} == {23, 20}
             break                                           # alors c'est qu'on a nos listes, on quitte la boucle
    solution = list(zip(l1, l2))

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Août 2015
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2015
    Messages : 43
    Points : 30
    Points
    30
    Par défaut
    Un grand merci pour avoir pris le temps de m'expliquer tout ça.
    C'est mieux que de pomper bêtement un code et de le coller sans savoir la mécanique.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Liste déroulante avec des conditions de saisie unique
    Par pagesalex dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 31/07/2018, 17h41
  2. Réponses: 45
    Dernier message: 06/03/2007, 16h30
  3. Makefile avec des conditions
    Par meufeu dans le forum Linux
    Réponses: 2
    Dernier message: 04/08/2006, 11h46
  4. Réponses: 1
    Dernier message: 30/06/2006, 16h01
  5. [ASE][T-SQL] Appel d'une sous-proc avec des conditions
    Par metheorn dans le forum Sybase
    Réponses: 1
    Dernier message: 19/05/2006, 18h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo