控制结构语句 循环语句
循环就是 重复做 某件事
一、for
for 变量名 in 可迭代对象:# 循环操作的代码
成员运算符:in 如果在指定的序列中找到值返回 True,否则返回 False。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。
迭代(遍历) 就是按照某种顺序逐个访问对象中的每一项。
Python 中有很多对象都是可以通过 for 语句来直接遍历的,例如 list、string、dict 等等,这些对象都是可迭代的,被称为可迭代对象。
可以将可迭代对象想象成一个容器,里面存放了有限个元素,并且每个元素都可以从中获取出来。那么这个容器就是可迭代的,这个容器就是可迭代对象。
range()
内置函数:range 函数用来 生成 包含连续多个整数的 range 对象,具体格式如下:
range(end) 或 range(start,end[,step])
参数说明:
- start:计数从 start 开始,默认是从 0 开始;
- end:计数到 end 结束,但是不包括 end;
- step:步长,默认为 1。
求 1 到100 的和
sum = 0 # 用于记录和for i in range(1, 101):sum += iprint(sum)
LCP 06. 拿硬币
class Solution: def minCount(self, coins: List[int]) -> int: res = 0 for x in coins: res += (x + 1) // 2 # 向上取整, x // 2 向下取整 return res
747. 至少是其他数字两倍的最大数
class Solution: def dominantIndex(self, nums: List[int]) -> int: # 方法一:最大值 >= 2 倍 次大值 first = second = id = 0 for i, x in enumerate(nums): if x > first: first, second = x, first id = i elif x > second: second = x return id if first >= 2 * second else -1 # 方法二:求最大值 ans = max_ = -1 for i, x in enumerate(nums): if x >= max_ * 2: ans = i # 当前的 max_ 对当前的 x 是满足条件的,先保存下来,但不一定是最终值。 elif x > max_ // 2: ans = -1 # 说明 max_ 不符合条件,先记 ans = -1 max_ = max(max_, x) return ans # 方法三:最大值函数 max_, ans = max(nums), -1 for i, x in enumerate(nums): if max_ == x: ans = i elif x > max_ // 2: return -1 return ans # 方法四:离线排序 q = sorted(range(len(nums)), key=lambda i:nums[i]) return -1 if nums[q[-2]]*2 > nums[q[-1]] else q[-1]
二、while
求 1 到100 的乘积
product = i = 1while i <= 100: product *= i i += 1print(product)
先理解题意,确定什么是 循环条件,什么是 循环体部分。
1518. 换酒问题
class Solution: def numWaterBottles(self, numBottles: int, numExchange: int) -> int: res = rem = numBottles # 全部喝完,rem 为空瓶数 while rem >= numExchange: numBottles, rem = divmod(rem, numExchange) # 可换酒 numBottles 瓶,剩余 rem 个空瓶。 res += numBottles # 全部喝完 rem += numBottles # + 空瓶 return res
2739. 总行驶距离
class Solution: def distanceTraveled(self, mainTank: int, additionalTank: int) -> int: ans = 0 while mainTank >= 5: mainTank -= 5 ans += 50 if additionalTank: additionalTank -= 1 mainTank += 1 return ans + mainTank * 10
快速模拟
class Solution: def distanceTraveled(self, mainTank: int, additionalTank: int) -> int: ans = 0 while mainTank >= 5: div, mainTank = divmod(mainTank, 5) ans += div * 50 add = min(div, additionalTank) additionalTank -= add mainTank += add return ans + mainTank * 10
1688. 比赛中的配对次数
class Solution: def numberOfMatches(self, n: int) -> int: res = 0 while n > 1: if n % 2 == 0: n //= 2 res += n else: res += n // 2 n = (n + 1) // 2 return res# return n - 1
三、break 和 continue
break 结束当前循环
continue 结束本次循环,继续判断条件执行下一次循环。
遍历列表 arr = [2, 3, 6, 4, 5, -1, 2, 5],求偶数的和,遇到 -1 终止遍历求和。
arr = [2, 3, 6, 4, 5, -1, 2, 5]sum_ = 0for x in arr: if x == -1: break if x % 2: continue sum_ += xprint(sum_)
四、else
循环语句和 else 配合使用,非 break 终止循环,即正常结束循环。
简单说:没有执行过 break,才执行 else 代码。
判断一个数是质数
n = 565345for i in range(2, n): if n % i == 0: print(n, "是合数") breakelse: print(n, "是质数")
输出 100 以内的素数
prime = []for i in range(2,100):# 如:int(97**0.5) = 9 循环 8 次就可以了,a = b*c,b 和 c 至少有一个 <= a 的平方根。 # for j in range(2,i): for j in range(2,int(i**0.5)+1): if not i % j: break else: prime.append(i)for i in prime: print(i, end=' ')
基础知识
divmod() 内置函数
divmod(a, b) 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
Python len() 内置函数
Python len() 返回对象(字符、列表、元组等)长度或项目个数。
Python range() 内置函数
range() 返回的是一个 可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表。
range(start, stop[, step])
参数说明:
start: 计数从 start 开始。默认是从 0 开始。例如 range(5)等价于range(0, 5);
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是 [0, 1, 2, 3, 4] 没有 5
step:步长,默认为 1。例如:range(0, 5) 等价于 range(0, 5, 1)
>>>range(10) # 从 0 开始到 9[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> range(1, 11) # 从 1 开始到 10[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>>> range(0, 30, 5) # 步长为 5[0, 5, 10, 15, 20, 25]>>> range(0, 10, 3) # 步长为 3[0, 3, 6, 9]>>> range(0, -10, -1) # 负数[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]>>> range(0)[]>>> range(1, 0)[]以下是 range 在 for 中的使用,循环出runoob 的每个字母:>>>x = 'runoob'>>> for i in range(len(x)) :... print(x[i])
Python enumerate() 内置函数
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
enumerate(sequence, [start=0])
参数
sequence – 一个序列、迭代器或其他支持迭代对象。
start – 下标起始位置的值。
返回 enumerate(枚举) 对象。
>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']>>> list(enumerate(seasons))[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]>>> list(enumerate(seasons, start=1)) # 下标从 1 开始[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
普通的 for 循环
>>> i = 0>>> seq = ['one', 'two', 'three']>>> for i in range(len(seq)):... print(i, seq[i])... i += 1
for 循环使用 enumerate
>>> seq = ['one', 'two', 'three']>>> for i, element in enumerate(seq):... print(i, element)
swap 交换
a, b = b, a # 右边取得的原来的值 注意和 a = b; b = a 不同。
整除
d, r = divmod(a, b) <=> d = a // b, r = a % b
// 整除
/ 除,结果是浮点数。
判断奇偶性
% 模运算符,n % 2
& 位运算符 与,n & 1 # 位运算符 与(&)
切片
切片指的是对序列进行截取,选取序列中的某一段。
切片的语法是: list[start:end:step]
以 冒号分割索引,start 代表 起点索引,end 代表 结束点索引。省略 start 表示以0开始,省略 end 表示到列表的结尾。注意,区间是左闭右开的!。分片不会修改原有的列表,可以将结果保存到新的变量。
如果提供的是负整数下标,则从列表的最后开始往头部查找。
切片过程中还可以设置 步长,以第二个冒号分割,例如 list[3:9:2],表示每隔多少距离取一个元素。
求和
sum(iterable[, start]) # python 内置函数
iterable – 可迭代对象,如:列表(list)、元组(tuple)、集合(set)、字典(dictionary)。
start – 指定相加的参数,如果没有设置这个值,默认为 0。
sum([1,2,3]) # in listsum([1,2,3],5) # in list +startsum((1,2,3)) # in tuplesum({1,2,3}) # in setsum({1:5,2:6,3:7}) # in dictionary keysum(range(1,4)) # in range()sum(i % 2 == 0 for i in position) # 生成器 偶数的个数
自己编写代码实现最大值和求和
arr = [1,2,3,4,5,6]max_ = -float("inf") # 注意初始化时取 arr 中最小数或更小的数,一般取无穷小 -float("inf")sum_ = 0 for x in arr:if x > max_: max_ = xsum_ += x # 累加print("最大值:", max_, "和:", sum_)
为什么数组下标是从 0 开始?
也不是所有的高级程序语言都是如此,比如 Python 数组下标就支持负数。
原因一:历史原因
语言出现顺序从早到晚 C、Java、JavaScript。
C 语言数组下标是从 0 开始-> Java 也是 -> JavaScript也是。
原因二:减少 CPU 指令运算
下标从 0 开始:
数组寻址——arr[i] = base_address + i * type_size --公式(1)
其中 base_address 为数组 arr 首地址,arr[0] 就是偏移量为 0 的数组,即数组 arr 首地址;i为偏移量,type_size 为数组类型字节数,比如 int 为 32 位,即4个字节。
下标从 1 开始:
数组寻址——arr[i] = base_address + (i -1)* type_size --公式(2)
比较两个计算公式可以发现公式(2)每次 CPU 寻址需要多一次 i-1 的操作,即多了一次减法的指令运算。
对于数组这种基础数据结构,无论在哪种高级程序语言中,都是频繁间接(作为容器的基础数据结构,比如 Java 的 ArrayList)或者直接被使用的,因此要尽量减少其消耗 CPU 资源。
原因三:物理内存的地址是从 0 开始的
计算机主存被抽象成由多个连续字节大小的单元组成的数组(逻辑地址),每个字节都对应唯一的物理地址,第一个字节的地址为0。
原因四:计算机组成原理
无论是二进制还是十进制,都要表示数字 1,只有 N(N进制)的 0 次方才能产生数字 1。
来源地址:https://blog.csdn.net/weixin_43955170/article/details/132909461