Jestem nowy w Pythonie i staram się zaprogramować funkcję wypełniającą macierz. Próbowałem napisać funkcję wykrywającą dla robota, ale zauważyłem coś, czego nie do końca rozumiałem. Wypełniam listę listy, wykonując iterację w pętli i sprawdzając warunek, aby wiedzieć, którą wartość przypisać. Kiedy drukuję bieżący element, program wydaje mi się dawać mi to, czego chcę, ale kiedy drukuję całą listę, jest ona wypełniona zerami. Jak to jest możliwe? Z góry dziękuję

p=[[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05]]
measurement='G'
sensor_right=0.7
colors = [['R','G','G','R','R'],['R','R','G','R','R'],['R','R','G','G','R'],['R','R','R','R','R']]
sensetable= [ [0.0] * len(p[0]) ]*len(p)
for i in range(len(p)):  
  for j in range(len(p[0])):
    if (colors[i][j]==measurement):
      sensetable[i][j]=1

    else:
      sensetable[i][j]=0


print(sensetable)

AKTUALIZACJA: Bardzo dziękuję za wszelką pomoc. To wszystko było częścią funkcji, która bierze pod uwagę prawdopodobieństwa zapisane w p. Załączam kod poniżej. Pomyślałem, że to najlepszy sposób, w jaki można to zrobić, czytając twoje odpowiedzi. Nie widzę sposobu na użycie zagnieżdżonego rozumienia list w tym przypadku, gdy potrzebuję p [i] [j] w moich obliczeniach wewnątrz pętli. Proszę mnie poprawić, jeśli się mylę lub jeśli masz dalsze sugestie. Dziękuję bardzo!!

def sense(p,measurement,sensor_right,colors):
sensetable=[]

for i in range(len(p)):
    aux=[]
    for j in range(len(p[0])):
        aux.append(p[i][j]*sensor_right if colors[i][j]==measurement else p[i][j]*(1-sensor_right))

    sensetable.append(aux)

norm=sum(sum(sensetable,[]))
probTableFin = [[float(j)/norm for j in i] for i in sensetable]

return probTableFin
0
Elisa Hidalgo 1 kwiecień 2020, 18:34

4 odpowiedzi

Najlepsza odpowiedź
sensetable = [[int(colors[i][j] == measurement) for j in range(len(p[i]))] for i in range(len(p))]

Awaria:

colors[i][j] == measurement zwraca wartość logiczną, int() konwertuje ją na 0/1

Wtedy jest to tylko podstawowe rozumienie listy. Skorzystaj z tego, aby uzyskać samouczek :)

I kod

p=[[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05],[0.05,0.05,0.05,0.05, 0.05]]
measurement='G'
sensor_right=0.7
colors = [['R','G','G','R','R'],['R','R','G','R','R'],['R','R','G','G','R'],['R','R','R','R','R']]
sensetable = [[int(colors[i][j] == measurement) for j in range(len(p[i]))] for i in range(len(p))]

print (sensetable)

# gives [[0, 1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]]

Wyjaśnienie, dlaczego Twój kod nie działa

Problematyczna linia to sensetable = [[0.0] * len(p[0])] * len(p)

Pozwól, że uproszczę to do sensetable = [[0] * 3] * 5. Działa tak samo, ma ten sam problem, łatwiejszy do wpisania i wyjaśnienia :)

W zasadzie w Pythonie a = [0] * 3 tworzy listę [0, 0, 0]. Nie ma problemu.

Jednak problem pojawia się, gdy dzwonisz pod numer b = [a] * 5. Spowoduje to utworzenie listy [a, a, a, a, a]. Jednak każdy z a na liście to to samo . Oznacza to, że są to to samo i mają ten sam adres pamięci, tj. Są przechowywane w tym samym miejscu w Twojej pamięci. Ponieważ mają ten sam adres w pamięci, kiedy zmienisz jeden z nich, zmienisz je wszystkie. To znaczy, jeśli powiesz b[0][0] = 1, zmieni się a[0] na 1, a lista stanie się [[1,0,0],[1,0,0],..] zamiast oczekiwanego [[1,0,0],[0,0,0],...].

Możesz to również zobaczyć, używając funkcji id.

a = [0] * 3
print (id(a[0]), id(a[1]), id(a[2]))

b = [a] * 5
print (id(b[0]), id(b[1]), id(b[2])) # All `id` are the same!

Aby to naprawić, zamień b = [a] * 5 na b = [a for _ in range(5)] lub równoważnie b = [[0] * 3 for _ in range(5)]. Spowoduje to utworzenie nowej kopii pliku a dla każdego b[0], b[1], b[2], b[3], b[4]. To sprawia, że wszyscy są rozłączeni i nie są ze sobą spokrewnieni.

c = [[0] * 3 for _ in range(5)]
print (id(c[0]), id(c[1]), id(c[2])) # Different id

Aby dowiedzieć się więcej: Lista uwzględnionych zmian w listach nieoczekiwanie na podlistach

0
Gareth Ma 1 kwiecień 2020, 15:50
sensetable = [[1 if letter==measurement else 0 for letter in color] for color in colors]

Nie musisz osobno definiować sensownego !! Objaśnienie kodu: powyższa lista zagnieżdżona przechodzi przez każdy element „kolorów” i sprawdza podany warunek. „kolor”: każda lista w „kolorach”, „litera”: każdy element każdej listy z kolorów. „pomiar”: „G”

0
Mehul Gupta 1 kwiecień 2020, 16:04

Problem

Notacja sensetable = [[0] * len(p[0])] * len(p) w rzeczywistości tworzy listę z jedną podlistą skopiowaną X razy, więc ponieważ ostatnia podlista do przeczytania zawiera tylko zera, wszystkie zera są na końcu.

print(sensetable) # [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
sensetable[0][0] = 15
print(sensetable) # [[15, 0, 0, 0, 0], [15, 0, 0, 0, 0], [15, 0, 0, 0, 0], [15, 0, 0, 0, 0]]

Rozwiązanie

Podczas iteracji wszystkich wartości nie musisz wstępnie wypełniać listy, po prostu zbuduj ją podczas iteracji

for i in range(len(p)):
    tmp = []
    for j in range(len(p[0])):
        if colors[i][j] == measurement:
            tmp.append(1)
        else:
            tmp.append(0)
    sensetable.append(tmp)

Poprawa

  1. W tekście if

    for i in range(len(p)):
        tmp = []
        for j in range(len(p[0])):
            tmp.append(1 if colors[i][j] == measurement else 0)
        sensetable.append(tmp)
    
  2. Popraw append, jak int(True)==1, int(False)==0 możesz zrobić

    tmp.append(colors[i][j] == measurement)
    
  3. Użyj rozumienia list raz

    for i in range(len(p)):
        sensetable.append([colors[i][j] == measurement for j in range(len(p[0]))])
    
  4. Używaj rozumienia listy dwa razy i nie używaj więcej indeksów, ale bezpośrednio elementy

    sensetable = [[int(letter == measurement) for letter in sublist] for sublist in colors]
    
0
azro 1 kwiecień 2020, 15:51

Zastąpić:

sensetable= [ [0.0] * len(p[0]) ]*len(p)

z:

sensetable = [[0 for _ in range(len(p[0]))] for _ in range(len(p))]

Lub lepiej

import numpy as np
sensetable = np.zeros((len(p), len(p[0])))
0
Shubham Sharma 1 kwiecień 2020, 15:47