Döngüler İçin İç İçe Tek Satır


104

Bir matrisin yerini değiştiren python'da bu işlevi yazdı:

def transpose(m):
    height = len(m)
    width = len(m[0])
    return [ [ m[i][j] for i in range(0, height) ] for j in range(0, width) ]

Bu süreçte, döngüler için tek satırın nasıl iç içe geçtiğini tam olarak anlamadığımı fark ettim. Lütfen aşağıdaki soruları yanıtlayarak anlamama yardımcı olun:

  1. Bu for döngüsünün çalıştırılma sırası nedir?
  2. Üçlü iç içe geçmiş bir for döngüsüm olsaydı, hangi sırayı çalıştırırdı?
  3. Eşit iç içe olmayan for döngüsüne eşit olan nedir?

Verilen,

[ function(i,j) for i,j in object ]
  1. Bunu for döngü yapısını kullanmak için nesne ne tür olmalıdır?
  2. İ ve j'nin nesnedeki öğelere atanma sırası nedir?
  3. Farklı bir for döngüsü yapısı ile simüle edilebilir mi?
  4. Bu for döngüsü, benzer veya farklı bir yapı for döngüsü ile iç içe olabilir mi? Ve nasıl görünürdü?

Ek bilgiler de takdir edilmektedir.

Yanıtlar:


171

En iyi bilgi kaynağı , liste kavrayışlarıyla ilgili resmi Python eğitimidir . Liste anlamaları, döngülerle hemen hemen aynıdır (kesinlikle herhangi bir liste anlama, bir for döngüsü olarak yazılabilir) ancak genellikle bir for döngüsü kullanmaktan daha hızlıdır.

Öğreticiden bu daha uzun liste anlayışına bakın ( ifbölüm, anlamayı filtreler, yalnızca if ifadesini geçen bölümler liste anlayışının son bölümüne aktarılır (burada (x,y)):

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Bu yuvalanmış for döngüsü ile tamamen aynıdır (ve öğreticide de söylendiği gibi, for ve if sırasının nasıl aynı olduğuna dikkat edin).

>>> combs = []
>>> for x in [1,2,3]:
...     for y in [3,1,4]:
...         if x != y:
...             combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

Bir liste anlama ile bir for döngüsü arasındaki en büyük fark , for döngüsünün son kısmının (bir şeyi yaptığınız yer) sonunda değil, başında gelmesidir.

Sorularınıza gelince:

Bunu for döngü yapısını kullanmak için nesne ne tür olmalıdır?

Bir iterable . Bir (sonlu) öğe kümesi oluşturabilen herhangi bir nesne. Bunlara herhangi bir kap, liste, set, jeneratör vb. Dahildir.

İ ve j'nin nesnedeki öğelere atanma sırası nedir?

Her listeden oluşturuldukları gibi tam olarak aynı sırada atanırlar, sanki iç içe geçmiş bir döngü içindeymiş gibi (ilk kavrayışınız için i için 1 öğe, ardından j'den her değer, 2. öğeden i'ye, sonra j'den her değer, vb.)

Farklı bir for döngüsü yapısı ile simüle edilebilir mi?

Evet, yukarıda zaten gösterilmiştir.

Bu for döngüsü, benzer veya farklı bir yapı for döngüsü ile iç içe olabilir mi? Ve nasıl görünürdü?

Elbette, ama bu harika bir fikir değil. Burada, örneğin size karakter listelerinin bir listesini verir:

[[ch for ch in word] for word in ("apple", "banana", "pear", "the", "hello")]

İkili yerleştirmede sipariş seçimlerini neyin yönlendirdiğini merak ediyorum. Diğer yolu daha doğal buluyorum (y için sonra x için örneğinizde). 3 yıl boyunca python yaptıktan (kapsamlı olarak değil ama yine de ...) ve bu tür döngüleri kullandıktan sonra farkındayım !!
Thomas

@Thomas ayrıca diğer yolu daha sezgisel buluyorum. İnandığım seçim tamamen kolaylıktı. Bunu daha sezgisel bir şekilde yapmak, daha sonra ifadede bulana kadar çözülmemiş sembollerle uğraşmak anlamına gelir. Kağıt üzerinde her şehirdeki muz mağazası her şehir için her muzda soymayı deneyin. O kadar kolay değil. Tersi de güzel ve kolay.
Pyjong

30

İlginizi çekebilir itertools.product, bu, onu ilettiğiniz tüm yinelenebilir değerlerden yinelenebilir bir değer demeti döndürür. Yani itertools.product(A, B)formun tüm değerlerini (a, b), adeğerlerin nereden geldiğini Ave bdeğerlerin nereden geldiğini verir B. Örneğin:

import itertools

A = [50, 60, 70]
B = [0.1, 0.2, 0.3, 0.4]

print [a + b for a, b in itertools.product(A, B)]

Bu yazdırır:

[50.1, 50.2, 50.3, 50.4, 60.1, 60.2, 60.3, 60.4, 70.1, 70.2, 70.3, 70.4]

Son argümanın nasıl itertools.product"içsel" argüman olduğuna dikkat edin . Genellikle eşittiritertools.product(a0, a1, ... an)[(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]


4

Her şeyden önce, ilk kodunuz kendi başına bir for döngüsü değil, bir liste anlama kullanır .

  1. Eşdeğeri olacaktır

    aralıktaki j için (0, genişlik): aralıktaki i için (0, yükseklik): m [i] [j]

  2. Aynı şekilde, genellikle sağdan sola döngüler gibi yuvalar. Ancak liste anlama sözdizimi daha karmaşıktır.

  3. Bu sorunun ne sorduğundan emin değilim


  1. Tam olarak iki nesne veren yinelenebilir nesneler üreten yinelenebilir herhangi bir nesne (ne ağız dolusu - yani [(1,2),'ab']geçerli olacaktır)

  2. Nesnenin yinelemeden sonra ortaya çıktığı sıra. ibirinci verime, jikinciye gider .

  3. Evet ama o kadar güzel değil. İşlevsel olarak şuna eşdeğer olduğuna inanıyorum:

    l = liste ()
    nesnede i, j için:
        l.append (işlev (i, j))
    

    hatta daha iyisi haritayı kullanın :

    map(function, object)

    Ama tabii işlevi almak zorunda kalacak i, jkendisi.

  4. Bu 3 ile aynı soru değil mi?


2

zipİşlevi kullanarak aynı satırdaki iki döngü için kullanabilirsiniz

Kod:

list1 = ['Abbas', 'Ali', 'Usman']
list2 = ['Kamran', 'Asgar', 'Hamza', 'Umer']
list3 = []
for i,j in zip(list1,list2):
    list3.append(i)
    list3.append(j)
print(list3)

Çıktı:

['Abbas', 'Kamran', 'Ali', 'Asgar', 'Usman', 'Hamza']

Yani, zip işlevini kullanarak, döngüler için iki kullanabiliriz veya aynı satırda iki listeyi yineleyebiliriz.


-1

İç içe döngüler için en iyi örnekler için aşağıdaki kod, iki for döngüsü kullanırken lütfen ilk döngünün çıktısının ikinci döngü için girdi olduğunu unutmayın. Yuvalanmış döngüleri kullanırken döngü sonlandırma da önemlidir

for x in range(1, 10, 1):
     for y in range(1,x):
             print y,
        print
OutPut :
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.