1. Characteristics of the first class of objects

#1. Function names can be assigned to variables as values
def func():
ret = func
print(ret)  #The address of the output func function

#2. Function names are stored in containers as elements
def func():
lst = [func,func,func]   #Put it in lst.
for i in lst:
    i()      # 1 1 1
#3. Function names can be used as parameters of functions
def func(f):
def foo():
func(foo)    #foo address to F 1 2

#4. Function names can be used as return values of functions
def func():
    def foo():
    return foo
ret = func()  #foo address 25
ret()  #Calling foo function    

2. formatting

f"Hello{'a'}"  #Fill in strings
F"Hello{'a'}"  # F
s = f"Hello{s1}"  #Fill variable
s = f"{35+15}"  #Filling calculation formula
s = f"{a if a > b else b}"  #Filling expression
s = f"{lst[0:2]}"  #Fill in lists and dictionaries

3. iterator

3.1 Iterable Objects

list, dic, str, set, tuple are all iterative objects, which are flexible to use.
1. list__iter__()
2. ctrl view source code
3. print(dir(list))

Official Statement: As long as the object has _iter_() method, it is an iterated object.
Advantages of Iterable Objects:
    1. Flexibility of use
    2. View values directly
 Disadvantage of Iterable Objects: Memory Consumption

Value selection method:
list,tuple,str -- index
 dict - key
 set -- Take the value directly

3.2 Iterator

# The official declaration is that as long as there is a _iter_() method _next_() method, it is an iterator.
lst = [1,2,3,4,6]
new_lst = lst.__iter__()  #Converting Iterable Objects into Iterators
print(new_lst.__next__()) #Print down an element from the previous position
#Errors will be reported when the iterator values exceed the range

#Iterator characteristics:
    #1. One-time (no more after use)
    #2. No retrograde (no retrograde)
    #3. Lazy mechanism (saving memory)
#When to use iterator: when the container data volume is large, use iterator.
s = [1,2,3,4,5,7]    # Changed version for loop
count = len(s)
new_s = s.__iter__()
while count:
    count -= 1

# The Essence of for Loop Implemented by while Loop
s = "12345"
new_s = s.__iter__()
while True:
    try:                        #Handle errors
        print(new_s.__next__()) # for the true essence
    except StopIteration: #When a StopIteration error occurs, close
    except Exception:   #Universal exception capture error

4. recursion

1. Constantly calling oneself (calling oneself) - dead cycle
   Maximum level 1000, actual test 997/998
 2. Clear Termination Conditions
 Satisfying the above two is effective recursion.
Delivery: Execute until the end condition is met
 Return: from the end of the condition to retreat
def age(n):
    if n == 3:
        return 30
        return age(n+1)-5
print(age(1))     # 20

#Unscramble above:
def age3(n):
    if n == 3:
        return 30
    # else:
    #     return age2(n+1)-5
def age2(n):
    if n == 3:
        return 30
        return age3(n+1)-5
def age1(n):
    if n == 3:
        return 30
        return age2(n+1)-5