บรรทัดเดียวซ้อนกันสำหรับลูป


104

เขียนฟังก์ชันนี้ใน python ที่เปลี่ยนเมทริกซ์:

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) ]

ในกระบวนการนี้ฉันตระหนักว่าฉันไม่เข้าใจอย่างถ่องแท้ว่าบรรทัดเดียวซ้อนกันเพื่อดำเนินการลูปอย่างไร โปรดช่วยฉันทำความเข้าใจโดยตอบคำถามต่อไปนี้:

  1. ลำดับของการดำเนินการลูปคืออะไร
  2. ถ้าฉันมีสามชั้นซ้อนกันสำหรับลูปมันจะดำเนินการอย่างไร
  3. อะไรจะเท่ากับ unested ที่เท่าเทียมกันสำหรับลูป?

ให้

[ function(i,j) for i,j in object ]
  1. ออบเจ็กต์ต้องเป็นประเภทใดจึงจะใช้โครงสร้างลูป
  2. ลำดับที่ i และ j กำหนดให้กับองค์ประกอบในออบเจ็กต์คืออะไร
  3. สามารถจำลองโดยใช้โครงสร้างลูปที่แตกต่างกันได้หรือไม่?
  4. สิ่งนี้สำหรับลูปสามารถซ้อนด้วยโครงสร้างที่คล้ายกันหรือต่างกันสำหรับลูปได้หรือไม่? แล้วหน้าตาจะเป็นยังไง?

ขอขอบคุณข้อมูลเพิ่มเติมเช่นกัน

คำตอบ:


171

แหล่งที่ดีที่สุดของข้อมูลที่เป็นทางการกวดวิชาหลามบน comprehensions ความเข้าใจในรายการเกือบจะเหมือนกับการวนซ้ำ (แน่นอนว่าความเข้าใจในรายการใด ๆ สามารถเขียนเป็น for-loop ได้) แต่มักจะเร็วกว่าการใช้ for loop

ดูการทำความเข้าใจรายการที่ยาวขึ้นนี้จากบทช่วยสอน ( ifส่วนนี้จะกรองความเข้าใจเฉพาะส่วนที่ผ่านคำสั่ง if เท่านั้นที่จะถูกส่งไปยังส่วนสุดท้ายของการทำความเข้าใจรายการ (ที่นี่(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)]

มันเหมือนกับสิ่งนี้ที่ซ้อนกันสำหรับลูป (และตามที่บทช่วยสอนบอกให้สังเกตว่าลำดับของ for และ if เหมือนกันอย่างไร)

>>> 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)]

ความแตกต่างที่สำคัญระหว่างความเข้าใจในรายการและสำหรับลูปคือส่วนสุดท้ายของ for loop (ที่คุณทำอะไรบางอย่าง) มาที่จุดเริ่มต้นแทนที่จะเป็นตอนท้าย

สำหรับคำถามของคุณ:

ออบเจ็กต์ต้องเป็นประเภทใดจึงจะใช้โครงสร้างลูป

ทำซ้ำได้ วัตถุใด ๆ ที่สามารถสร้างชุดองค์ประกอบ (จำกัด ) ซึ่งรวมถึงคอนเทนเนอร์รายการชุดเครื่องกำเนิดไฟฟ้า ฯลฯ

ลำดับที่ i และ j กำหนดให้กับองค์ประกอบในออบเจ็กต์คืออะไร

พวกเขาถูกกำหนดในลำดับเดียวกันกับที่สร้างขึ้นจากแต่ละรายการราวกับว่าพวกมันอยู่ในวงซ้อนสำหรับลูป (สำหรับความเข้าใจครั้งแรกของคุณคุณจะได้รับ 1 องค์ประกอบสำหรับ i จากนั้นทุกค่าจาก j, องค์ประกอบที่ 2 เป็น i, จากนั้นทุกค่าจาก j ฯลฯ )

สามารถจำลองโดยใช้โครงสร้างลูปที่แตกต่างกันได้หรือไม่?

ใช่แสดงไว้แล้วด้านบน

สิ่งนี้สำหรับลูปสามารถซ้อนด้วยโครงสร้างที่คล้ายกันหรือต่างกันสำหรับลูปได้หรือไม่? แล้วหน้าตาจะเป็นยังไง?

แน่นอน แต่ไม่ใช่ความคิดที่ดี ตัวอย่างเช่นที่นี่จะให้รายชื่อตัวละคร:

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

ฉันสงสัยว่าอะไรเป็นแนวทางในการเลือกสั่งซื้อในรังซ้อน ฉันพบวิธีอื่นที่เป็นธรรมชาติกว่า (สำหรับ y แล้วสำหรับ x ในตัวอย่างของคุณ) ฉันเพิ่งรู้ว่าหลังจาก 3 ปีของการทำ python (ไม่ใช่อย่างกว้างขวาง แต่ก็ยัง ... ) และการใช้ลูปแบบนั้น !!
Thomas

@ โทมัสฉันยังพบวิธีอื่นที่ใช้งานง่ายกว่า ทางเลือกที่ฉันเชื่อคือความสะดวกอย่างแท้จริง การทำเช่นนี้เป็นวิธีที่ง่ายกว่านั้นจะหมายถึงการต้องจัดการกับสัญลักษณ์ที่ไม่ได้รับการแก้ไขจนกว่าจะพบในคำสั่งในภายหลัง ลองแยกวิเคราะห์กล้วยแต่ละอันปอกกล้วยแต่ละเมืองสำหรับแต่ละเมือง Bananastore ในแต่ละเมืองบนกระดาษ ไม่ง่ายเหมือนกัน วิธีอื่น ๆ แม้ว่าดีและง่าย
Pyjong

30

คุณอาจสนใจitertools.productซึ่งส่งคืนค่าทูเปิลที่ให้ผลซ้ำได้จากการทำซ้ำทั้งหมดที่คุณส่งผ่าน นั่นคือitertools.product(A, B)ผลตอบแทนถัวเฉลี่ยค่าทั้งหมดของแบบฟอร์ม(a, b)ที่aค่ามาจากAและค่ามาจากb Bตัวอย่างเช่น:

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)]

สิ่งนี้พิมพ์:

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

สังเกตว่าอาร์กิวเมนต์สุดท้ายส่งผ่านไปitertools.productยัง "ภายใน" อย่างไร โดยทั่วไปจะเท่ากับitertools.product(a0, a1, ... an)[(i0, i1, ... in) for in in an for in-1 in an-1 ... for i0 in a0]


4

แรกของทุกรหัสแรกของคุณไม่ได้ใช้สำหรับวงต่อ se แต่เข้าใจรายการ

  1. ก็จะเทียบเท่ากับ

    สำหรับ j ในช่วง (0, width): สำหรับ i ในช่วง (0, height): m [i] [j]

  2. ในทำนองเดียวกันโดยทั่วไปรังเหมือนสำหรับลูปจากขวาไปซ้าย แต่ไวยากรณ์ของความเข้าใจในรายการมีความซับซ้อนกว่า

  3. ฉันไม่แน่ใจว่าคำถามนี้กำลังถามอะไร


  1. วัตถุที่ทำซ้ำได้ใด ๆ ที่ให้วัตถุที่ทำซ้ำได้ซึ่งให้ผลลัพธ์สองวัตถุ (สิ่งที่ถูกปาก - กล่าวคือ[(1,2),'ab']จะถูกต้อง)

  2. ลำดับที่วัตถุให้ผลเมื่อทำซ้ำ iไปที่ผลตอบแทนแรกjที่สอง

  3. ใช่ แต่ไม่สวยเท่า ฉันเชื่อว่ามันใช้งานได้เทียบเท่ากับ:

    l = รายการ ()
    สำหรับ i, j ในวัตถุ:
        l.append (ฟังก์ชัน (i, j))
    

    หรือดีกว่าใช้แผนที่ :

    map(function, object)

    แต่แน่นอนการทำงานจะต้องได้รับi, jตัวเอง

  4. คำถามนี้ไม่ใช่คำถามเดียวกับ 3 หรือไม่?


2

คุณสามารถใช้สองสำหรับลูปในบรรทัดเดียวกันโดยใช้zipฟังก์ชัน

รหัส:

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)

เอาท์พุต:

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

ดังนั้นโดยใช้ฟังก์ชัน zip เราสามารถใช้สองรายการสำหรับลูปหรือเราสามารถทำซ้ำสองรายการในแถวเดียวกัน


-1

ด้านล่างโค้ดสำหรับตัวอย่างที่ดีที่สุดสำหรับลูปที่ซ้อนกันในขณะที่ใช้สองลูปสำหรับลูปโปรดจำไว้ว่าเอาต์พุตของลูปแรกคืออินพุตสำหรับลูปที่สอง การสิ้นสุดลูปยังมีความสำคัญในขณะที่ใช้ลูปที่ซ้อนกัน

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.