Hướng dẫn recursive list of lists python - danh sách đệ quy của danh sách python

Hoàn toàn không có gì sai khi truyền một danh sách như một đối số cho chức năng đệ quy của bạn và không sửa đổi nó. Trong thực tế, làm như vậy làm cho nó khá tầm thường để giải quyết vấn đề.

Hãy xem xét một phiên bản nhỏ của vấn đề: Chỉ có 3 bước. Bạn đang ở dưới cùng của cầu thang. Bạn có thể thực hiện một bước, hai bước hoặc ba bước. Sau đó, bạn có 3 vấn đề phụ để giải quyết:

  • Tất cả các giải pháp bắt đầu với đường dẫn
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    print(find_paths(4))
    
    6, đi thêm 2 bước.
  • Tất cả các giải pháp bắt đầu với đường dẫn
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    print(find_paths(4))
    
    7, đi thêm 1 bước.
  • Tất cả các giải pháp bắt đầu với đường dẫn
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    print(find_paths(4))
    
    8, đi thêm 0 bước.

Có vẻ như một khởi đầu tốt cho giải pháp đệ quy.

Hãy tập trung vào những người đầu tiên trong số các vấn đề phụ này. Đường dẫn của bạn là

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
6 và bạn có 2 bước bổ sung để đi. Từ đây, bạn có thể thực hiện 1 bước, 2 bước hoặc 3 bước. Bạn một lần nữa có 3 vấn đề phụ:

  • Tất cả các giải pháp bắt đầu với đường dẫn
    from functools import lru_cache
    
    @lru_cache()
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    paths = find_paths(10)
    print(len(paths))
    print(find_paths.cache_info())
    
    0, đi thêm 1 bước.
  • Tất cả các giải pháp bắt đầu với đường dẫn
    from functools import lru_cache
    
    @lru_cache()
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    paths = find_paths(10)
    print(len(paths))
    print(find_paths.cache_info())
    
    1, đi thêm 0 bước.
  • Tất cả các giải pháp bắt đầu với đường dẫn
    from functools import lru_cache
    
    @lru_cache()
    def find_paths(remaining):
    
       paths = []
       if remaining == 0:
          paths.append([])
       for step in range(1,3+1):
           if step <= remaining:
              subpaths = find_paths(remaining - step)
              for subpath in subpaths:
                 paths.append([step] + subpath)
    
       return paths
    
    paths = find_paths(10)
    print(len(paths))
    print(find_paths.cache_info())
    
    2, đi -1 các bước bổ sung.

Bài toán phụ đầu tiên đòi hỏi nhiều công việc hơn ... một cuộc gọi đệ quy khác, sẽ trả lại

from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
3. Bài toán phụ thứ hai sẽ trả lại chỉ đường mà chúng tôi đã đi để đến đây:
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
4. Và vấn đề phụ cuối cùng sẽ không trả lại giải pháp:
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
5. Chúng tôi thêm các giải pháp này với nhau
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
6 để có được
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
7 và trả lại điều đó.

Sao lưu, vấn đề phụ thứ hai, "Bắt đầu với đường dẫn

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
7, đi thêm 1 bước" sẽ trả về
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
9 như là tập hợp các giải pháp. Bài toán con thứ ba, "Bắt đầu với đường dẫn
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
8, đi 0 bước bổ sung" sẽ trả về
listA = [10, 20, 30]
listB = [1, 2, 3, listA]
1. Thêm các giải pháp này cùng với
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
7 cung cấp giải pháp hoàn chỉnh:
listA = [10, 20, 30]
listB = [1, 2, 3, listA]
3

Theo mã:

def find_paths(total):

   def helper(path, remaining):
      paths = []
      if remaining == 0:
         paths.append(path)
      elif remaining > 0:
         for step in range(1,3+1):
            paths.extend( helper(path + [step], remaining - step))
      return paths

   return helper([], total)

print(find_paths(3))

Đầu ra, như mong đợi, là:

[[1, 1, 1], [1, 2], [2, 1], [3]]


Tất nhiên, bạn không phải vượt qua

listA = [10, 20, 30]
listB = [1, 2, 3, listA]
4, danh sách các bước hiện tại, vào cuộc gọi đệ quy. Thay vào đó, bạn chỉ có thể yêu cầu tất cả các đường dẫn từ bước hiện tại đến đỉnh cầu thang, và tiền tố những người với bước chỉ được thực hiện. Chúng tôi thậm chí không cần một người trợ giúp trong trường hợp này:

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))

Đầu ra, như mong đợi, là:

[[1, 1, 1], [1, 2], [2, 1], [3]]

Tất nhiên, bạn không phải vượt qua

listA = [10, 20, 30]
listB = [1, 2, 3, listA]
4, danh sách các bước hiện tại, vào cuộc gọi đệ quy. Thay vào đó, bạn chỉ có thể yêu cầu tất cả các đường dẫn từ bước hiện tại đến đỉnh cầu thang, và tiền tố những người với bước chỉ được thực hiện. Chúng tôi thậm chí không cần một người trợ giúp trong trường hợp này:

from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())

[[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1]]
CacheInfo(hits=17, misses=11, maxsize=128, currsize=11)

Cần lưu ý rằng

listA = [10, 20, 30]
listB = [1, 2, 3, listA]
5 sẽ được gọi - và sẽ trả về các đường dẫn tương tự,
listA = [10, 20, 30]
listB = [1, 2, 3, listA]
6 - sau khi tăng dần hai bước đầu tiên, một lần tại một thời điểm với đường dẫn
from functools import lru_cache

@lru_cache()
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

paths = find_paths(10)
print(len(paths))
print(find_paths.cache_info())
0 hoặc khi một bước nhảy hai bước với đường dẫn
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
7. Vì nó trả về cùng một giá trị, thay vì tính toán lại tất cả các đường dẫn từ thời điểm đó, chúng ta có thể lưu trữ kết quả và sử dụng lại giá trị trên các bước tiếp theo.

Hướng dẫn sử dụng, Chương 5: Danh sách danh sách, chức năng và đệ quy

Trong chương cuối, chúng tôi đã thảo luận về danh sách Python, làm thế nào đối tượng

for number in listB:
    print(number)
2 tương tự như một danh sách và làm thế nào chúng ta có thể đặt các đối tượng
for number in listB:
    print(number)
3 vào một
for number in listB:
    print(number)
2, nhìn vào độ lệch của chúng và
for number in listB:
    print(number)
5
for number in listB:
    print(number)
2 trong musicxml hoặc dưới dạng văn bản. Chúng tôi đã kết thúc bằng cách đặt một
for number in listB:
    print(number)
2 vào một
for number in listB:
    print(number)
2 khác, có vẻ như là một mẹo gọn gàng cho đến khi chúng tôi phát hiện ra rằng chúng tôi không thể nhận được các yếu tố bên trong
for number in listB:
    print(number)
2 bên trong.

Trong chương này, chúng tôi sẽ làm việc về cách khai thác sức mạnh của

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
0 lồng nhau. Chúng tôi sẽ bắt đầu với một cuộc thảo luận về các danh sách đệ quy (vì
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
0 hoạt động rất nhiều như danh sách). Những người có một số chương trình có thể sẽ muốn bỏ qua phần sau.

Danh sách (tương tự như các mảng trong các ngôn ngữ khác) có thể chứa tất cả các loại khác bên trong chúng bao gồm các danh sách khác. Vì vậy, hãy để bắt đầu bằng cách tạo hai danh sách:

listA = [10, 20, 30]
listB = [1, 2, 3, listA]

Bây giờ khi chúng ta nhìn vào LISTB, chúng ta sẽ thấy rằng lista ở bên trong nó:

Lưu ý rằng khi chúng ta nhìn vào độ dài (

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
2) của ListB, nó cho thấy rằng có 4 yếu tố, không phải 6:

Điều đó bởi vì yếu tố thứ tư của ListB (mà bạn nhớ lại, được gọi là

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
3 không phải
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
4) tự nó là một danh sách, lista:

Vì vậy, nếu chúng ta muốn có được yếu tố thứ ba của Lista, có một cách dễ dàng để làm điều đó:

Nhưng chúng ta cũng có thể nghĩ rằng

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
5 cũng là yếu tố thứ ba của yếu tố thứ tư của listb. Vì vậy, chúng tôi có thể viết cái này thay thế:

Ồ, và vì mỗi trong số này là các yếu tố cuối cùng của danh sách tương ứng của họ, thay vào đó chúng ta có thể viết:

có nghĩa là "Nhận phần tử cuối cùng của yếu tố cuối cùng của ListB"

Nhưng điều gì sẽ xảy ra nếu chúng ta chỉ muốn biết mọi số được lưu trữ ở bất cứ đâu trong listb, ngay cả khi số đó nằm trong danh sách? Điều này đã giành được công việc:

for number in listB:
    print(number)

Thay vào đó, chúng tôi phải kiểm tra xem liệu mỗi số của người Viking trong

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
6 có thực sự là một số hoặc một danh sách không. Và nếu nó có một danh sách, chúng ta nên tìm mỗi số trong đó và in nó thay thế. Ở đây, một bộ lệnh phức tạp hơn một chút để làm điều đó:

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)

Điều đó đã làm điều đó! Làm thế nào nó hoạt động? Chà, chúng tôi nhìn vào từng điều của người Viking trong

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
6 - chúng tôi gọi nó là điều mà ở đây, bởi vì chúng tôi không chắc chắn liệu nó có phải là một số danh sách không. Sau đó, trong dòng tiếp theo
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
8 kiểm tra xem điều đó là danh sách. Nếu đó là
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
9 thì chúng ta sẽ đến một vòng lặp bên trong, nơi chúng ta nhìn vào Thing Thing (trong trường hợp này là
listC = [100, 200, 300, listB]
0, nhưng chương trình không biết điều đó) và nhận được số số từ đó. Nhưng nếu điều đó không phải là một danh sách, thì đó là nơi mà
listC = [100, 200, 300, listB]
1 xuất hiện, đó là những gì chúng ta chạy nếu chúng ta không có danh sách, điều đó chỉ nói, in số.

.

Các chức năng và đệ quy

Nhưng nếu chúng ta làm điều này:

listC = [100, 200, 300, listB]

Bây giờ kể từ khi ListB chứa List, chúng tôi kết thúc với một danh sách trong danh sách trong danh sách:

 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]

Nếu chúng tôi muốn in tất cả các số trong LISTC, chúng tôi có thể viết một bộ lệnh xấu xí như thế này (Tôi sẽ hiểu nếu bạn không thực sự muốn gõ cái này và chỉ muốn tin tôi rằng điều này hoạt động):

for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)

 100
 200
 300
 1
 2
 3
 10
 20
 30

Whew! Nếu đây là cách duy nhất để làm điều đó, tôi sẽ đổ lỗi cho bạn nếu bạn quyết định rằng lập trình chỉ là điều đáng đau đầu. Đặc biệt là vì bạn có lẽ đã đoán rằng chúng ta có thể thực hiện:

listC = [100, 200, 300, listB]
3 và nhận được một lớp danh sách khác. May mắn thay, có một chút phép thuật lập trình có tên là Recurmedion mà chúng ta có thể sử dụng để đi đến trung tâm của vấn đề. Lưu ý rằng trong mã tôi vừa viết, có một vài dòng về cơ bản giống nhau (với một vài từ đã thay đổi) như các phần khác của mã. Với mã hóa đệ quy, chúng tôi sẽ tìm cách lưu các dòng đó để sử dụng lại chúng. Nhập sáu dòng sau:

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
0

Những gì chúng tôi đã thực hiện được tạo ra một chức năng mới có tên là ‘Cơn phẳng, trong danh sách các danh sách và in bất cứ thứ gì trong đó.

Bây giờ cố gắng:

 100
 200
 300
 1
 2
 3
 10
 20
 30

Nó hoạt động! Nhưng bằng cách nào? Ở đây, cách thức hoạt động của các chức năng nói chung (bỏ qua điều này, nếu bạn biết tất cả về các chức năng):

Tuyên bố

listC = [100, 200, 300, listB]
4 nói rằng chúng tôi sẽ định nghĩa một chức năng mới. Sau khi từ
listC = [100, 200, 300, listB]
4 xuất hiện tên của hàm - thứ mà chúng tôi sẽ có thể gọi nó để sử dụng nó sau. . với các biến, các vấn đề trường hợp trong Python, vì vậy
listC = [100, 200, 300, listB]
6 không giống như
listC = [100, 200, 300, listB]
8 hoặc
listC = [100, 200, 300, listB]
9 hoặc
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
0.)

Sau khi Flatprint, trong ngoặc đơn xuất hiện tên biến

 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1. Lưu ý rằng chúng tôi đã sử dụng tên
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1 - nó không tồn tại. Điều
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1 có nghĩa là ở đây là bất cứ khi nào chúng ta sử dụng hàm
listC = [100, 200, 300, listB]
6, bất kể tên của danh sách là gì, trong
listC = [100, 200, 300, listB]
6 nó sẽ được gọi là
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1. Vì vậy, bạn có thể nói
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
7, như chúng tôi vừa làm, và trong hàm
listC = [100, 200, 300, listB]
6,
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
9 sẽ được gọi là
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1.

Ở đây, một chức năng đơn giản hơn sẽ giải thích điều đó tốt hơn.

for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
1 có một số và in hình vuông của nó:

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
2

Bây giờ chúng ta có thể thử:

Lưu ý hai điều trong trường hợp cuối cùng. Đầu tiên rằng Pi không chính xác là 3.14 - tất cả chúng ta đều biết điều đó; Tôi chỉ muốn đảm bảo các giáo viên toán trong phòng didn đi vào các mối quan hệ. Thứ hai, chúng tôi đã cho biến

for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
2 cho hàm
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
1. Nhưng trong hàm
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
1, chúng tôi đã viết:
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
5; Thay vào đó, trong hàm,
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
2 (hoặc bất kỳ biến hoặc số nào khác) sẽ được gọi đơn giản là
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
7. .

Khi kết thúc một hàm, bạn có thể

 100
 200
 300
 1
 2
 3
 10
 20
 30
0 ra một cái gì đó hoặc
 100
 200
 300
 1
 2
 3
 10
 20
 30
1 một giá trị, có thể được sử dụng cho bất cứ điều gì khác. Ở đây, ____ ____992 hoạt động rất giống
for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
1, nhưng nó phân lập số lượng và thay vì in nó, nó trả lại nó:

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
3

Bởi vì chúng tôi không in

for thing in listC:
    if isinstance(thing, list):
        for innerThing in thing:
            if isinstance(innerThing, list):
                for number in innerThing:
                    print(number)
            else:
                print(innerThing)
    else:
        print(thing)
7, chúng tôi có thể gán giá trị của khối cho một biến khác:

Lưu ý rằng nếu

 100
 200
 300
 1
 2
 3
 10
 20
 30
5 và
 100
 200
 300
 1
 2
 3
 10
 20
 30
6 thì chúng ta có thể thay thế
 100
 200
 300
 1
 2
 3
 10
 20
 30
7 cho
 100
 200
 300
 1
 2
 3
 10
 20
 30
8 và viết:

Do đó, sử dụng

 100
 200
 300
 1
 2
 3
 10
 20
 30
1 thay vì
 100
 200
 300
 1
 2
 3
 10
 20
 30
0 mạnh hơn, vì vậy sau khi kết thúc với
listC = [100, 200, 300, listB]
6, chúng tôi chủ yếu viết
 100
 200
 300
 1
 2
 3
 10
 20
 30
1 chứ không phải
 100
 200
 300
 1
 2
 3
 10
 20
 30
0 chức năng.

Vì vậy, trở lại

listC = [100, 200, 300, listB]
6, mà bạn sẽ nhớ là (Tôi đã thêm các số dòng nhận xét một lần nữa để tôi có thể tham khảo chúng):

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
4

Hãy cùng nhìn vào nó từng dòng.

Dòng 1, như chúng tôi đã nói, xác định chức năng được gọi là

listC = [100, 200, 300, listB]
6 mà mong đợi một danh sách mà chúng tôi sẽ gọi là
 [100, 200, 300, [1, 2, 3, [10, 20, 30]]]
1.

Dòng 2, nói rằng đối với mỗi thứ bên trong Mylist, hãy lấy nó và gọi nó là ____107. Sau khi chúng tôi hoàn thành với

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
07, chương trình sẽ quay trở lại dòng 2 để có được điều tiếp theo.

Dòng 3, kiểm tra xem

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
07 là một danh sách. Nếu vậy, chúng tôi làm dòng 4. Nếu không chúng tôi nhảy đến dòng 5.

Dòng 4: Đây là nơi phép thuật xảy ra. Bây giờ chúng tôi biết rằng

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
07 là một danh sách. Vậy làm thế nào để chúng ta in một danh sách (có thể có các danh sách khác bên trong nó)? Chúng tôi sử dụng
listC = [100, 200, 300, listB]
6! Về bản chất
listC = [100, 200, 300, listB]
6 sử dụng sức mạnh riêng biệt giữa các danh sách và số để in bất kỳ danh sách nội bộ nào. Chúng tôi gọi các chức năng sử dụng (Call Call) Các hàm đệ quy và quá trình sử dụng các hàm đệ quy được gọi là đệ quy. Nó là một công cụ mạnh mẽ và chúng tôi sẽ sử dụng trong Music21 rất nhiều.

Dòng 5, là nơi chúng tôi nhảy đến từ dòng 3 nếu

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
07 không phải là một danh sách, vì vậy sau đó Python thực thi dòng 6

Dòng 6, chỉ đơn giản là in

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
07, mà chúng ta biết bây giờ là một số.

Một cảnh báo: Không giống như một số ngôn ngữ lập trình (Java, C, v.v.), Python không bao giờ kiểm tra xem những gì bạn chuyển sang

listC = [100, 200, 300, listB]
6 thực sự là một danh sách. Vì vậy, bạn có thể thử làm một cái gì đó như
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
16 nhưng vì
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
5 không phải là một danh sách, bạn sẽ gặp lỗi:

def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
5

Để biết thêm thông tin về các cấu trúc dữ liệu (danh sách, danh sách danh sách và những điều chúng tôi đã không nhận được, tôi khuyên bạn nên xem hướng dẫn của Google Google Python, đặc biệt là lớp 2).

Gói (lại¶

Trong chương này, chúng tôi đã xem xét cách chúng tôi có thể xem xét các danh sách bên trong danh sách, điều này sẽ rất quan trọng khi chúng tôi xem xét cách làm việc với

for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
0 của
for thing in listB:
    if isinstance(thing, list):
        for number in thing:
            print(number)
    else:
        print(thing)
0 trong Music21, để xem
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
20 trong
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
21 trong vòng
def find_paths(remaining):

   paths = []
   if remaining == 0:
      paths.append([])
   for step in range(1,3+1):
       if step <= remaining:
          subpaths = find_paths(remaining - step)
          for subpath in subpaths:
             paths.append([step] + subpath)

   return paths

print(find_paths(4))
22. Chúng tôi cũng đã học cách xác định một hàm và viết các chức năng đệ quy để thực hiện công việc mạnh mẽ chỉ trong một vài dòng mã. Trong chương tiếp theo, chúng tôi áp dụng tất cả điều này vào âm nhạc với các luồng của các luồng.Streams of Streams.