For döngüsü içinde liste tanımlama?

Merhaba python’a ve siteye yeniyim. basit bir tic tac toe kodunda liste üreteci kullanılmış, ben yerine içiçe for döngüsü kullanmak istediğimde program aynı çıktıyı neden vermiyor anlayamadım. oyun kodunu uzun olmasın diye en sade haline getirdim bu kod işi görüyor:

kazanma_ölçütleri = [[[0, 0], [1, 0], [2, 0]],
                     [[0, 1], [1, 1], [2, 1]],
                     [[0, 2], [1, 2], [2, 2]],
                     [[0, 0], [0, 1], [0, 2]],
                     [[1, 0], [1, 1], [1, 2]],
                     [[2, 0], [2, 1], [2, 2]],
                     [[0, 0], [1, 1], [2, 2]],
                     [[0, 2], [1, 1], [2, 0]]]

o_durumu = [[0, 1], [1, 1], [0, 0], [2, 2]]

for i in kazanma_ölçütleri:
        o = [z for z in i if z in o_durumu]  
        if len(o) == len(i):
            print(o)
            print("o kazandı")

Bense o = [z for z in i if z in o_durumu] yerine:

o = []
for i in kazanma_ölçütleri:
for z in i:
	if z in o_durumu
	o += [z]
    if len(o) == len(i):
           print(o)
           print("o kazandı")

o listesi: o_durumundaki itemler kazanma ölçütlerinde de varsa o’ya ekleniyor. o listesi kazanma ölçütlerindekiyle aynı sayıya ulaşınca kazandı çıktısı veriyor.

şöyle bir kod kullanmaya çalıştım(anlamak için), ama yanlış sonuç veriyor. o=[] listesini for döngüsü içinde tanımlarsam da boş çıktı alıyorum. Henüz her şeyin mantığını kavramış değilim, neden o listesini for döngüsü içine alınca çıktı vermiyor? burada içiçe for döngüleri yerine liste üretecini kullanma zorunluluğu nerden geliyor? Biri bu olayın mantığını anlamama yardım ederse çok sevinirim, teşekkürler şimdiden.

Oncelikle kodun duzgun gorundugu ve neredeyse calistigi icin takdir ederim. Buraya gelen cogu insan kodunu bodoslama yapistirip gidiyor, “alin cozun, ben ugrasamayacagim” dercesine. Empati yoksunu bir kultur—neyse, pardon.

Ipucu surada:

o = [z for z in i if z in o_durumu]

Fark ilk kodda o listesinin tekrar tekrar yaratilmasi. Her i ile birlikte (isimler de kotuymus) yeni bir o yaratiliyor. Ikinci kodda o buyuyup duruyor.

Ikinci koddaki o = []'i kazanma_ölçütleri loop’unun icine alirsak veya ilk koddaki

o = [z for z in i if z in o_durumu]  

'i

o += [z for z in i if z in o_durumu]  

yaparsak kodlar ayni calisiyor.

Bu arada i “index”'in kisaltmasi veya “bu ufacik for loop’undaki kullanimindan ne oldugu bariz oldugu icin isim vermeye gerek duymadigim integer (tamsayi)” olarak kullaniliyor. Bu durumda kazanma_ölçütü daha dogru bir isim olacaktir.

o icin daha iyi bir isim bulamiyorum cunku ne ise yaradigini anlamadim.

Cunku “kazanma olcutu” de kotu bir isim—cunku “olcut” soyut bir kavram. “Kazanan hamleler” veya “Kazanma koordinatlari” gibi bir isim daha iyi olabilirdi?

z okey cunku ufacik bir loop’ta, ne oldugu bariz bir sekilde kullanilmis :slight_smile:

1 Beğeni

Bu aslında istihza’nın python eğitiminden örnek bir tic tac toe oyunuydu kodları en yalın halde çalışacak şekilde kırptım ama değişken adlarını aynı bırakınca anlaşılmaz olmuş k.bakmayın :slight_smile:
o listesini += ile denemek hiç aklıma gelmemişti. Yani tersten düşününce -doğru anladıysam- liste üretecinin avantajı “o” listesini her i için tekrar tekrar oluşturması, böylece “o” listesi vaktinden önce dolup yanlış çıktı vermiyor.
ikinci kodda,

for i in kazanma_ölçütleri:
    o = []
    for z in i:
        if z in o_durumu:
            o += [z]
        if len(o) == len(i):
               print(o)
               print("o kazandı")

bu şekilde o’yu içeri alırsam doğru sonucu verdi. Dün uğraşırken doğru sonucu alamamıştım, boş çıktı veriyordu for içine alınca. Eğitimde de, bu kodda içiçe for yerine liste üreteci kullanmak gerekiyor yazıyordu. Sanırım sebebi başkaymış. Yani for döngüsü içinde de bu şekilde liste oluşturulabiliyormuş. Cevabınız için çok teşekkür ederim :slight_smile:

Ha, pardon, istihza’ya hakim degilim, link verilmeden alinti yapildigini anlamiyorum :slight_smile: O zaman bahsettigim isimlendirme elestirileri orijinal kod icin de gecerli olsa gerek.

Hah, evet, kodu simdi anladim. Niye len’in kontrol edildigini de…

O buyuk liste “kazanan_pozisyon_kombinasyonlari”. Her hangi bir kombinasyonun tamaminda “O” varsa “O” kazaniyor.

Yani o_durumu da aslinda o_[gecmis/oynanmis]_hamleleri.

Evet, her kazanan pozisyon uclusu icin oynanmis pozisyonlari yeniden degerlendirmek lazim, yoksa mesela ust satir uclusune yapilmis bir hamle alt satir uclusundeki tas sayisini arttiriyor.

Liste uretecinin avantaji kodu kisaltip yerine gore daha okunur hale getirmesi.

kareler = []
for x in range(KARE_SAYISI):
    kareler.append(x * x)

yerine

kareler = [x*x for x in range(KARE_SAYISI)]

Ayni zamanda bir expression (ifade) oldugu icin kendisi bir degere sahip; degisken kullanmayi secime bagli yapiyor:

kareler = []
for x in range(KARE_SAYISI):
    kareler.append(x * x)
print(kareler)

vs.

print([x*x for x in range(KARE_SAYISI)])

Aslinda listenin elemanlarini fonksiyondan geciren map (+filter) islemini yapiyor:

def kare(x): return x*x
print(list(map(kare, range(KARE_SAYISI))))

liste üreteçlerini yeni öğrenirken çok karışık geldiği için içiçe forlara dönüştürünce daha anlamlı gelir mantığını anlarım diye düşünmüştüm. Dönüştürürken de bir sürü şey öğrenmiş oldum :slight_smile:

Bu arada değişkenleri isimlendirme konusunda verdiğiniz ipuçları için teşekkür ederim, bu konuda da tecrübesizim. Daha somut isimler vermeye çalışıcam.

Henüz map konusunu öğrenmedim o yüzden bu kısma öğrendikten sonra dönüp bakmayı planlıyorum.

Bir de bu kadar çabuk cevap geleceğini düşünmemiştim. Buraya yolum sık sık düşecek gibi. Vakit ayırıp yardımcı olduğunuz için tekrar teşekkürler.