循环就是 重复做 某件事
for 变量名 in 可迭代对象:
# 循环操作的代码
成员运算符:in 如果在指定的序列中找到值返回 True,否则返回 False。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。
迭代(遍历) 就是按照某种顺序逐个访问对象中的每一项。
Python 中有很多对象都是可以通过 for 语句来直接遍历的,例如 list、string、dict 等等,这些对象都是可迭代的,被称为可迭代对象。
可以将可迭代对象想象成一个容器,里面存放了有限个元素,并且每个元素都可以从中获取出来。那么这个容器就是可迭代的,这个容器就是可迭代对象。
内置函数:range 函数用来 生成 包含连续多个整数的 range 对象,具体格式如下:
range(end) 或 range(start,end[,step])
参数说明:
求 1 到100 的和
sum = 0 # 用于记录和
for i in range(1, 101):
sum += i
print(sum)
class Solution:
def minCount(self, coins: List[int]) -> int:
res = 0
for x in coins:
res += (x + 1) // 2 # 向上取整, x // 2 向下取整
return res
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]
求 1 到100 的乘积
product = i = 1
while i <= 100:
product *= i
i += 1
print(product)
先理解题意,确定什么是 循环条件,什么是 循环体部分。
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
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
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 结束本次循环,继续判断条件执行下一次循环。
遍历列表 arr = [2, 3, 6, 4, 5, -1, 2, 5],求偶数的和,遇到 -1 终止遍历求和。
arr = [2, 3, 6, 4, 5, -1, 2, 5]
sum_ = 0
for x in arr:
if x == -1:
break
if x % 2:
continue
sum_ += x
print(sum_)
循环语句和 else 配合使用,非 break 终止循环,即正常结束循环。
简单说:没有执行过 break,才执行 else 代码。
判断一个数是质数
n = 565345
for i in range(2, n):
if n % i == 0:
print(n, "是合数")
break
else:
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(a, b) 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。
Python len() 返回对象(字符、列表、元组等)长度或项目个数。
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])
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)
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 list
sum([1,2,3],5) # in list +start
sum((1,2,3)) # in tuple
sum({1,2,3}) # in set
sum({1:5,2:6,3:7}) # in dictionary key
sum(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_ = x
sum_ += x # 累加
print("最大值:", max_, "和:", sum_)
也不是所有的高级程序语言都是如此,比如 Python 数组下标就支持负数。
语言出现顺序从早到晚 C、Java、JavaScript。
C 语言数组下标是从 0 开始-> Java 也是 -> JavaScript也是。
1、下标从 0 开始:
数组寻址——arr[i] = base_address + i * type_size --公式(1)
其中 base_address 为数组 arr 首地址,arr[0] 就是偏移量为 0 的数组,即数组 arr 首地址;i为偏移量,type_size 为数组类型字节数,比如 int 为 32 位,即4个字节。
2、下标从 1 开始:
数组寻址——arr[i] = base_address + (i -1)* type_size --公式(2)
比较两个计算公式可以发现公式(2)每次 CPU 寻址需要多一次 i-1 的操作,即多了一次减法的指令运算。
对于数组这种基础数据结构,无论在哪种高级程序语言中,都是频繁间接(作为容器的基础数据结构,比如 Java 的 ArrayList)或者直接被使用的,因此要尽量减少其消耗 CPU 资源。
3、原因三:物理内存的地址是从 0 开始的
计算机主存被抽象成由多个连续字节大小的单元组成的数组(逻辑地址),每个字节都对应唯一的物理地址,第一个字节的地址为0。
4、原因四:计算机组成原理
无论是二进制还是十进制,都要表示数字 1,只有 N(N进制)的 0 次方才能产生数字 1。