我有一个元组,它给了我这样的东西:
(array([115, 115, 295], dtype=int64), array([377, 378,404], dtype=int64))
现在我想将其转换为这样的集合:
{(115,377),(115,378),(295,404)}
我目前正在使用这种方法:
def edges2cordinate(edges):
l = int(len(edges[0]))
res=set()
for i in range (0,len):
res.add((edges[0][i],edges[1][i]))
return res
但是给我错误。
回溯(最近通话最近): 文件“ F:\ canny_vertices.py”,第40行,在打印中(edges2cordinate(indices)) 文件“ F:\ canny_vertices.py”,第16行,在edge2坐标中,i的范围为(0,len): TypeError:“ builtin_function_or_method”对象无法解释为整数
我想念什么?
答案 0 :(得分:3)
在您之前的代码中,您想做range (0,l)
而不是range (0,len)
,因为您已经将长度变量保存在l
中,所以您希望将该长度传递给{ {1}}变量而不是内置函数range
一旦这样做,原始代码就可以正常工作
len
输出将为
def edges2cordinate(edges):
l = int(len(edges[0]))
res=set()
for i in range (0,l):
res.add((edges[0][i],edges[1][i]))
return res
print(edges2cordinate([[115, 115, 295],[377, 378,404]]))
但这也可以通过{(295, 404), (115, 378), (115, 377)}
轻松完成,我们在其中解压缩列表列表,将其作为参数传递给zip
,然后将压缩的迭代器转换回zip
,请注意,由于set
set
输出将为li = [[115, 115, 295],[377, 378,404]]
print(set(zip(*li)))
要反转项目,只需在反转列表时通过反转元组的各个元素来创建集合,即可反转它们!
{(295, 404), (115, 378), (115, 377)}
输出将为li = [[115, 115, 295],[377, 378,404]]
print(set((y,x) for x, y in zip(*li)))
答案 1 :(得分:2)
使用zip
进行包装:
list(zip(*tupl)) # where tupl is your tuple
输出与您的期望相反的值列表。但是我猜这可能更适合,因为这样可以删除重复项并且没有顺序。
答案 2 :(得分:0)
def edges2cordinate(edges):
res = set()
for i in range(len(edges[0])):
res.add((edges[0][i], edges[1][i]))
return res
edge = ([115, 123, 295], [377, 378, 404])
res = edges2cordinate(edge)
set(reversed(list(res)))
这还会提供正确的输出{(115, 377), (115, 378), (295, 404)}
,如果您不熟悉zip
,这是一个更简单的解决方案。上面已正确回答了您的代码无法正常工作的原因。
答案 3 :(得分:0)
为了解释如何获得所有其他答案,我们从整理(固定)的OP原始代码版本开始:
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
第二,请注意,在edges
循环的每次迭代中,我们一直获取for
的第一和第二个元素。 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
,方法是为它提供多个可以迭代的内容,例如list
或数组,然后将它们压缩,返回包含您所提供内容的元组。例如:
list(zip([1,2,3], [4,5,6]))
评估为[(1,4), (2,5), (3,6)]
。 list()
周围的原因是(在Python 3中)zip
为您提供了一个迭代器,并将此迭代器传递给list()
将为您提供包含该迭代器中各项的列表。 / p>
第三,在上述代码上使用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]
转到{的第一个参数{1}},zip
转到第二个参数,依此类推。
Python给您提供的另一种工具generator expressions,可让我们将其中许多工具转换为一行:
edges[1]
但是我们不会使用此生成器表达式“做任何事情”,因此可以将其删除,以简化操作:
def edges2cordinate(edges):
return set(pair_i for pair_i in zip(*edges))
在后续评论中,您询问了如何反转边缘的顺序。一种方法是:
def edges2cordinate(edges):
return set(zip(*edges))
有望完成明显的任务。建议的reversed()
函数可能会达到您的期望,但可以用作:
def edges2cordinate(edges):
return set(zip(edges[1], edges[0]))
保持最小化