Le but de mon code est de créer une liste de listes qui contient toutes les combinaisons de deux commutateurs sur une liste binaire.

Par exemple, un commutateur à deux de [1,0,0,1,0] serait [0,0,0,1,1]

J'ai écrit du code qui effectue le premier changement. J'essaie d'écrire du code qui prend l'entrée des premiers commutateurs et effectue un deuxième commutateur. L'ordre de l'entrée est basé sur l'endroit où le premier changement a été effectué. Ainsi, la première liste d'éléments avait son premier commutateur dans son premier élément, la deuxième liste d'éléments avait son commutateur dans le deuxième élément, etc. Je ne changerai pas ces éléments car cela annulerait le premier commutateur.

Voici ce que j'ai. La liste nbrhood est la liste hypothétique des listes qui ont déjà eu un commutateur

import itertools

n = 4
nbrhood = [[1,1,1,1],[0,0,0,0]]
nbrhood2 = list(itertools.chain.from_iterable(itertools.repeat(x, (n-1)) for x in nbrhood))
print(nbrhood2)


h = 0
f = 0   
for j in range(0,6):

    f = j//(n-1)

    if n <= h:
        h = 0

    if h != f and h <= n:
        if nbrhood2[j][h] == 1:
            nbrhood2[j][h] = 0
        else:
            nbrhood2[j][h] = 1
        h = h + 1
    elif h == f and h <= n:
        if nbrhood2[j][h+1] == 1:
            nbrhood2[j][h+1] = 0 
        else:
            nbrhood2[j][h+1] = 1  
        h = h + 2
    elif h >= n:
        h = 0

    print(nbrhood2[j])

Voici la sortie inattendue:

[1, 0, 1, 1]
[1, 0, 0, 1]
[1, 0, 0, 0]
[1, 0, 0, 0]
[1, 0, 1, 0]
[1, 0, 1, 1]

J'ai besoin que la sortie ressemble à ceci:

[1, 0, 1, 1]
[1, 1, 0, 1]
[1, 1, 1, 0]
[1, 0, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 1]

Je ne comprends pas que la modification que j'apporte à une liste dans nbrhood2 s'applique également aux autres listes. Comme la façon dont le 0 placé en deuxième position dans la première liste va également en deuxième position dans la deuxième liste.

J'y travaille depuis des heures sans aucune explication réelle. J'imagine que cela a quelque chose à voir avec la façon dont Python traite les changements de liste bidimensionnels, mais je n'ai pas pu le comprendre.

0
Jarom 15 avril 2018 à 08:25

3 réponses

Meilleure réponse

Les listes en Python sont toujours par référence. Vous répétez littéralement les valeurs imbriquées de dans nbrhood lorsque vous faites itertools.repeat(x, (n-1)) for x in nbrhood.

Copiez simplement la liste complète en remplaçant le premier x par x[:]:

itertools.repeat(x[:], (n-1)) for x in nbrhood
1
jkinkead 15 avril 2018 à 05:46

Vous pouvez parcourir tous les éléments du premier commutateur et, dans une boucle imbriquée, parcourir tous les éléments suivants du deuxième commutateur. Faire démarrer la boucle intérieure à l'élément après l'index de la boucle extérieure garantit que vous ne dupliquez pas votre couverture.

def two_switch(original):
    list_of_2_switches = []
    for i in range(len(original)):
        one_switch = original[:] #copy to retain original
        one_switch[i]=1-one_switch[i]
        for j in range(i+1, range(len(original))):
            second_switch=one_switch[:]
                second_switch[j] = 1-second_switch[j]
            lit_of_2_switches.append(second_switch)
    return list_of_2_switches
0
Bennett Brown 15 avril 2018 à 05:51

Il est assez simple de créer une liste avec toutes les combinaisons

 l  = list(itertools.product([0,1], repeat=4))
[[i] for i in l]

Production

[[(0, 0, 0, 0)], [(0, 0, 0, 1)], [(0, 0, 1, 0)], [(0, 0, 1, 1)], [(0, 1, 0, 0)], [(0, 1, 0, 1)], [(0, 1, 1, 0)], [(0, 1, 1, 1)], [(1, 0, 0, 0)], [(1, 0, 0, 1)], [(1, 0, 1, 0)], [(1, 0, 1, 1)], [(1, 1, 0, 0)], [(1, 1, 0, 1)], [(1, 1, 1, 0)], [(1, 1, 1, 1)]]
0
MikiBelavista 15 avril 2018 à 05:42