为了解释如何获得所有其他答案,我们从 OPs 原始代码的整理(和固定)版本开始:
def edges2cordinate(edges):
num_entries = len(edges[0])
res = set()
for i in range(0, num_entries):
res.add((edges[0][i], edges[1][i]))
return res
第一次清理发生在注意到range() 允许传递单个参数之后,导致它从零计数到该参数。我们还注意到num_entries 只使用了一次,所以我们可以将它移动到使用它的位置,给我们:
def edges2cordinate(edges):
res = set()
for i in range(len(edges[0])):
res.add((edges[0][i], edges[1][i]))
return res
其次,请注意,在for 循环的每次迭代中,我们都会不断获取edges 的第一个和第二个元素。 Python 为我们提供了“assignment expressions”(PEP 572),这让我们可以这样写:
def edges2cordinate(edges):
first_arr, second_arr = edges
res = set()
for i in range(len(first)):
res.add((first_arr[i], second_arr[i]))
return res
而且应该会快一点,因为我们只需要将项目取出一次,而不是每次循环迭代。
每个答案都指向使用zip() 使这段代码更简洁。你使用zip 给它多个可以迭代的东西,比如lists 或你的数组,然后它会压缩它们,给你返回包含你给它的东西中的项目的元组。例如:
list(zip([1,2,3], [4,5,6]))
计算为[(1,4), (2,5), (3,6)]。 list() 包围它的原因是(在 Python 3 中)zip 给你一个迭代器,并将这个迭代器传递给 list() 给你一个包含来自该迭代器的项目的列表。
第三,在上述代码中使用zip 的最小变化是:
def edges2cordinate(edges):
first_arr, second_arr = edges
res = set()
for first_item_i, second_item_i in zip(first_arr, second_arr):
res.add((first_item_i, second_item_i))
return res
此外,我们正在使用这些“赋值表达式”来冗余地将它们分开并将它们组合在一起,因此我们可以将其重写为:
def edges2cordinate(edges):
res = set()
for pair_i in zip(edges[0], edges[1]):
res.add(pair_i)
return res
我们也可以改为使用zip(*edges),其中“unpacks”edges 成为zip 的参数,即edges[0] 转到zip 的第一个参数,edges[1] 转到第二个参数等
Python 为您提供的另一个工具是generator expressions,它可以让我们将很多内容变成一行:
def edges2cordinate(edges):
return set(pair_i for pair_i in zip(*edges))
但我们并没有对这个生成器表达式“做任何事情”,所以可以将其删除,达到极简主义:
def edges2cordinate(edges):
return set(zip(*edges))
在后续评论中,您询问了如何反转边缘的顺序。一种方法是:
def edges2cordinate(edges):
return set(zip(edges[1], edges[0]))
这有望做显而易见的事情。建议的 reversed() 函数可能符合您的预期,但可以用作:
def edges2cordinate(edges):
return set(zip(*reversed(edges)))
尽量减少