首页 > 解决方案 > 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

标签: pythondata-structures

解决方案


当您有两个范围并且想要分别循环它们以获取所有组合时,您可以使用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 函数mapfilter与 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))

不会太复杂以至于无法理解。

请注意,像productand一样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)]

推荐阅读