python - Python 理解——替换嵌套循环
问题描述
解决“二和”问题。
输入:一个未排序的数组 A(整数)和一个目标总和 t
目标:返回元组对 (x,y) 的列表,其中 x + y = t
我已经实现了一个哈希表 H 来存储 A 的内容。通过使用嵌套循环遍历 H,我实现了所需的输出。然而,本着学习 Python 艺术的精神,我想用一个很好的 1-liner 替换嵌套循环,使用理解和一个可能的 lambda 函数?建议?
源代码:
import csv
with open('/Users/xxx/Developer/Algorithms/Data Structures/_a.txt') as csvfile:
csv_reader = csv.reader(csvfile, delimiter ='\n')
hash_table = {int(num[0]):int(num[0]) for(num) in csv_reader} #{str:int}
def two_sum(hash_table, target):
pairs = list()
for x in hash_table.keys():
for y in hash_table.keys():
if x == y:
continue
if x + y == target:
pairs.append((x,y))
return pairs
解决方案
当您有两个范围并且想要分别循环它们以获取所有组合时,您可以使用itertools.product
. 您可以替换下面的代码
range1 = [1,2,3,4]
range2 = [3, 4, 5]
for x in range1:
for y in range2:
print(x, y)
和
from itertools import product
for x, y in product(range1, range2):
print(x, y)
两个代码块都产生
1 3
1 4
1 5
2 3
2 4
2 5
3 3
3 4
3 5
4 3
4 4
4 5
但是您仍然需要if
使用此构造进行检查。但是,product
返回的是一个生成器,您可以将其作为可迭代对象传递给 lambda 函数map
或filter
与 lambda 函数一起传递。
在您的情况下,您只想包含符合条件的对。因此,filter
就是你想要的。在我的简单示例中,如果我们只想要总和为偶数的组合,那么我们可以执行类似的操作
gen = product(range1, range2)
f = lambda i: (i[0] + i[1]) % 2 == 0
desired_pairs = filter(f, gen)
这可以写成一个单行
desired_pairs = filter(lambda i: (i[0] + i[1]) % 2 == 0, product(range1, range2))
不会太复杂以至于无法理解。
请注意,像product
and一样map
,过滤器返回的是一个生成器,如果您稍后要循环它来做一些其他工作,这很好。如果您真的需要一个列表,只需将其转换为列表
desired_pairs = list(filter(lambda i: (i[0] + i[1]) % 2 == 0, product(range1, range2)))
如果我们打印这个,我们会得到
[(1, 3), (1, 5), (2, 4), (3, 3), (3, 5), (4, 4)]
推荐阅读
- apache - 使用 .htaccess mod_rewrite 将部分 URL 重写到特定页面
- html - 一个 div 与另一个 div 对接时包装,而不是堆叠在其上
- c# - 无法加载文件或程序集 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一
- go - 在golang中动态创建结构数组
- ruby-on-rails - RSpec Controller 测试屏幕上的文本失败
- graph-databases - 如何在 JanusGraph 中合并两个顶点并删除其中一个。还将删除顶点的边添加到修改的顶点
- javascript - 数据表行中的链接行为与数据表外的链接行为不同
- mysql - 需要为mysql适配脚本
- ruby-on-rails - Rails:创建按日期包含值的多个系列图表
- entity-framework-core - 是否有一种与数据库无关的方法来执行带有参数的存储过程