当前位置:   article > 正文

Python-VBA函数之旅-divmod函数

Python-VBA函数之旅-divmod函数

目录

1、divmod函数:

1-1、Python:

1-2、VBA:

2、相关文章:

个人主页:非风V非雨-CSDN博客



        divmod函数在Python中具有广泛的应用场景,特别是在需要同时处理除法的商和余数的情况下。常见的应用场景有:

1、分页显示:
当处理大量数据并需要在多个页面上显示这些数据时,divmod()函数非常有用。例如,在网页上展示商品列表或搜索结果时,通常会将数据分成多页显示。divmod()函数可以帮助你确定每页应该显示多少项,以及当前页是第几页。

2、循环和迭代:
在编写循环时,有时需要知道当前循环的次数以及相对于某个固定值的余数。divmod()函数可以同时提供这些信息,这在周期性任务或模式匹配中非常有用。

3、时间单位转换:
处理时间相关的问题时,经常需要将秒数转换为小时、分钟和秒的组合。divmod()函数可以方便地执行这种转换,因为它可以一次性得到除法的商和余数。

4、文件处理:
当处理大型文件时,可能需要将数据分成多个块进行处理。divmod()函数可以帮助确定每个块的大小以及剩余的部分,这对于流式处理或分块处理大文件非常有用。

5、算法实现:
在编写某些算法时,如欧几里得算法(用于计算最大公约数)或其他涉及除法和取余操作的算法时,divmod()函数可以简化代码并提高性能。

6、性能优化:
相比于分别使用`//`和`%`运算符进行除法和取余操作,divmod()函数提供了更高效的解决方案。因为它可以一次性完成两个操作,减少了重复计算的可能性,从而提高了代码的执行效率。

        总之,divmod()函数在处理需要同时知道除法的商和余数的场景时非常有用。它可以简化代码逻辑,提高性能,并在各种实际应用中发挥重要作用。

1、divmod函数:
1-1、Python:
  1. # 1.函数:divmod
  2. # 2.功能:用于返回两个数值(非复数)相除得到的商和余数组成的元组,即获取两个数值的商和余数组成的元组
  3. # 3.语法:divmod(a, b)
  4. # 4.参数:
  5. # 4-1. a:被除数
  6. # 4-2. b:除数
  7. # 5.返回值:返回由商和余数组成的元组
  8. # 6.说明:
  9. # 6-1、若a、b两个参数,全部或其中之一是复数,则会报TypeError错误,如下:
  10. # TypeError: unsupported operand type(s) for divmod(): 'complex' and 'complex'
  11. # a = 2 + 3j
  12. # b = 5 + 6j
  13. # print(divmod(a, b))
  14. # TypeError: unsupported operand type(s) for divmod(): 'int' and 'complex'
  15. # a = 2
  16. # b = 5 + 6j
  17. # print(divmod(a, b))
  18. # TypeError: unsupported operand type(s) for divmod(): 'complex' and 'int'
  19. # a = 2 + 3j
  20. # b = 5
  21. # print(divmod(a, b))
  22. # 6-2、通过divmod函数获取商和余数的元组时,元组中的第一个元素为商,第二个元素为余数:
  23. # 6-2-1、如果参数a和b都是整数,则相当于(a//b, a%b)
  24. # 6-2-2、如果参数a或b是浮点数,则相当于(math.floor(a/b), a%b)
  25. # 6-3、输入参数类型:divmod()函数接受两个参数,它们都应该是可以进行整数除法运算的类型,通常是整数。如果你尝试对非整数类型(如浮点数或字符串)使用divmod()函数,将会引发`TypeError`
  26. # 6-4、返回值类型:divmod()函数返回一个包含两个元素的元组:商和余数。这两个元素都是整数类型。因此,在接收divmod()函数的返回值时,需要确保使用元组解包或其他适当的方式来处理这两个值
  27. # 6-5、余数符号:divmod()函数返回的余数总是非负的,并且其符号与除数(而不是被除数)相同。这是Python整数除法行为的一部分,即总是向零舍入。因此,即使商是负数,余数也始终是非负的
  28. # 6-6、整数除法与浮点除法:divmod()函数执行的是整数除法,即只返回整数结果。如果你需要浮点数的结果,应该使用普通的除法运算符`/`
  29. # 6-7、性能考虑:虽然divmod()函数在同时需要商和余数时很方便,但在只需要其中一个结果的情况下,使用单独的`//`(整数除法)或`%`(取余)运算符可能更为高效,因为它们避免了不必要的计算
  30. # 6-8、处理零除数:当你使用divmod()函数时,应确保除数不为零,因为零除数会导致`ZeroDivisionError`异常。在实际应用中,你可能需要添加额外的检查来处理这种情况
  31. # 6-9、边界情况:在处理非常大的整数或特殊的边界情况时(如整数的最小值和最大值),你需要确保你的代码能够正确处理这些情况,以避免溢出或其他意外的行为
  32. # 7.示例:
  33. # 应用1:分页显示
  34. def paginate(items, page_size):
  35. """
  36. 对项目进行分页处理,并返回指定页的项目列表
  37. :param items: 包含所有项目的列表
  38. :param page_size: 每页显示的项目数量
  39. :return: 当前页的项目列表
  40. """
  41. # 计算总页数
  42. total_pages = divmod(len(items), page_size)[0] + (1 if len(items) % page_size > 0 else 0)
  43. # 获取用户请求的页码(这里为了示例简化为命令行输入)
  44. page_number = int(input(f"请输入页码(1-{total_pages}): "))
  45. # 确保页码在有效范围内
  46. if page_number < 1 or page_number > total_pages:
  47. print("页码无效,请输入有效页码。")
  48. return []
  49. # 计算当前页的开始和结束索引
  50. start_index = (page_number - 1) * page_size
  51. end_index = start_index + page_size
  52. # 返回当前页的项目列表
  53. return items[start_index:end_index]
  54. # 主函数
  55. if __name__ == '__main__':
  56. items = list(range(1, 1011)) # 假设有1011个项目,编号为1到1011
  57. page_size = 24 # 每页显示24个项目
  58. # 获取并打印第2页的项目
  59. page_2_items = paginate(items, page_size)
  60. print(f"第2页的项目: {page_2_items}")
  61. # 请输入页码(1-43): 41
  62. # 第2页的项目: [961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984]
  63. # 应用2:循环和迭代
  64. def iterate_with_divmod(items, interval):
  65. """
  66. 使用divmod在迭代中计算索引和余数
  67. :param items: 要迭代的列表
  68. :param interval: 间隔,用于计算余数
  69. """
  70. for index, item in enumerate(items):
  71. quotient, remainder = divmod(index, interval)
  72. print(f"Index: {index}, Item: {item}, Quotient: {quotient}, Remainder: {remainder}")
  73. # 主函数
  74. if __name__ == '__main__':
  75. items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
  76. interval = 3 # 假设我们每3个元素作为一个间隔
  77. iterate_with_divmod(items, interval)
  78. # Index: 0, Item: a, Quotient: 0, Remainder: 0
  79. # Index: 1, Item: b, Quotient: 0, Remainder: 1
  80. # Index: 2, Item: c, Quotient: 0, Remainder: 2
  81. # Index: 3, Item: d, Quotient: 1, Remainder: 0
  82. # Index: 4, Item: e, Quotient: 1, Remainder: 1
  83. # Index: 5, Item: f, Quotient: 1, Remainder: 2
  84. # Index: 6, Item: g, Quotient: 2, Remainder: 0
  85. # Index: 7, Item: h, Quotient: 2, Remainder: 1
  86. # Index: 8, Item: i, Quotient: 2, Remainder: 2
  87. # Index: 9, Item: j, Quotient: 3, Remainder: 0
  88. # 应用3:时间单位转换
  89. def convert_seconds(total_seconds):
  90. """
  91. 将总秒数转换为小时、分钟和秒的组合
  92. :param total_seconds: 总秒数
  93. :return: 一个包含小时、分钟和秒的元组
  94. """
  95. # 将总秒数转换为小时和剩余的秒数
  96. hours, seconds_remainder = divmod(total_seconds, 3600)
  97. # 将剩余的秒数转换为分钟和剩余的秒数
  98. minutes, seconds = divmod(seconds_remainder, 60)
  99. return hours, minutes, seconds
  100. # 主函数
  101. if __name__ == '__main__':
  102. total_seconds = 1024 # 假设有1024秒,需要转换
  103. hours, minutes, seconds = convert_seconds(total_seconds)
  104. print(f"{total_seconds}秒 等于 {hours}小时 {minutes}分钟 {seconds}秒")
  105. # 1024秒 等于 0小时 17分钟 4秒
  106. # 应用4:文件处理
  107. def split_file(input_file, output_prefix, records_per_file):
  108. """
  109. 将大型文本文件分割成多个小文件,每个文件包含指定数量的记录
  110. :param input_file: 输入文件的路径
  111. :param output_prefix: 输出文件的前缀
  112. :param records_per_file: 每个输出文件应包含的记录数
  113. """
  114. with open(input_file, 'r') as file:
  115. current_file_index = 0
  116. current_record_count = 0
  117. output_file = None
  118. for line in file:
  119. # 假设每行是一个记录
  120. current_record_count += 1
  121. # 使用divmod来确定是否应开始新文件
  122. quotient, remainder = divmod(current_record_count, records_per_file)
  123. if remainder == 0 and quotient > current_file_index:
  124. # 关闭当前输出文件(如果有的话)
  125. if output_file:
  126. output_file.close()
  127. # 创建新的输出文件
  128. current_file_index += 1
  129. output_filename = f"{output_prefix}_{current_file_index}.txt"
  130. output_file = open(output_filename, 'w')
  131. # 将记录写入当前输出文件
  132. output_file.write(line)
  133. # 关闭最后一个输出文件
  134. if output_file:
  135. output_file.close()
  136. # 主函数
  137. if __name__ == '__main__':
  138. input_file_path = 'file.txt' # 假设这是一个非常大的文本文件
  139. output_file_prefix = 'split_file' # 输出文件的前缀
  140. records_per_output_file = 1000 # 每个输出文件应包含的记录数
  141. split_file(input_file_path, output_file_prefix, records_per_output_file)
  142. # 应用5:算法实现
  143. # 首先,我们需要了解斐波那契数列的矩阵表示形式:
  144. # | F(n+1) F(n) | = | 1 1 |^n
  145. # | F(n) F(n-1)| | 1 0 |
  146. # 其中,F(n) 表示斐波那契数列的第 n 项。
  147. def matrix_multiply(a, b):
  148. """
  149. 矩阵乘法
  150. """
  151. return [[a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1]],
  152. [a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1]]]
  153. def matrix_power(matrix, n):
  154. """
  155. 矩阵的快速幂算法
  156. """
  157. result = [[1, 0], [0, 1]] # 初始化为单位矩阵
  158. base = matrix
  159. while n > 0:
  160. quotient, remainder = divmod(n, 2)
  161. if remainder == 1:
  162. result = matrix_multiply(result, base)
  163. base = matrix_multiply(base, base)
  164. n = quotient
  165. return result
  166. def fibonacci(n):
  167. """
  168. 使用矩阵快速幂算法计算斐波那契数列的第n项
  169. """
  170. if n <= 0:
  171. return "输入错误:n必须为正整数"
  172. elif n == 1:
  173. return 0
  174. elif n == 2:
  175. return 1
  176. else:
  177. # 定义斐波那契数列的转移矩阵
  178. fib_matrix = [[1, 1], [1, 0]]
  179. # 计算矩阵的n-1次方(因为F(1)和F(2)已知)
  180. power_matrix = matrix_power(fib_matrix, n - 1)
  181. # 提取结果矩阵的第一行第一列元素,即为F(n)
  182. return power_matrix[0][0]
  183. # 主函数
  184. if __name__ == '__main__':
  185. n = 10 # 计算斐波那契数列的第10项
  186. print(f"斐波那契数列的第{n}项是:{fibonacci(n)}")
  187. # 斐波那契数列的第10项是:55
  188. # 应用6:性能优化
  189. import time
  190. import random
  191. def process_numbers_with_divmod(numbers, divisor):
  192. results = []
  193. for number in numbers:
  194. quotient, remainder = divmod(number, divisor)
  195. results.append((quotient, remainder))
  196. return results
  197. def process_numbers_without_divmod(numbers, divisor):
  198. results = []
  199. for number in numbers:
  200. quotient = number // divisor
  201. remainder = number % divisor
  202. results.append((quotient, remainder))
  203. return results
  204. if __name__ == '__main__':
  205. # 生成一些测试数据
  206. numbers = [random.randint(1, 10000) for _ in range(100000)]
  207. divisor = 100
  208. # 使用divmod的版本
  209. start_time_divmod = time.time()
  210. divmod_results = process_numbers_with_divmod(numbers, divisor)
  211. end_time_divmod = time.time()
  212. print(f"使用divmod的版本耗时: {end_time_divmod - start_time_divmod}秒")
  213. # 不使用divmod的版本
  214. start_time_no_divmod = time.time()
  215. no_divmod_results = process_numbers_without_divmod(numbers, divisor)
  216. end_time_no_divmod = time.time()
  217. print(f"不使用divmod的版本耗时: {end_time_no_divmod - start_time_no_divmod}秒")
  218. # 检查两个函数的结果是否相同
  219. assert divmod_results == no_divmod_results
  220. # 使用divmod的版本耗时: 0.015990734100341797秒
  221. # 不使用divmod的版本耗时: 0.0219879150390625秒
1-2、VBA
略,待后补。
2、相关文章:

2-1、Python-VBA函数之旅-bytes()函数 

2-2、Python-VBA函数之旅-callable()函数

2-3、Python-VBA函数之旅-classmethod()函数 

2-4、Python-VBA函数之旅-compile()函数 

Python算法之旅:Algorithm

Python函数之旅:Functions 

个人主页:非风V非雨-CSDN博客
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/585247
推荐阅读
相关标签
  

闽ICP备14008679号