将元组设置为坐标

时间:2019-05-09 16:57:43

标签: python

我有一个元组,它给了我这样的东西:

(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

Code link

但是给我错误。

回溯(最近通话最近):   文件“ F:\ canny_vertices.py”,第40行,在打印中(edges2cordinate(indices))   文件“ F:\ canny_vertices.py”,第16行,在edge2坐标中,i的范围为(0,len): TypeError:“ builtin_function_or_method”对象无法解释为整数

我想念什么?

4 个答案:

答案 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),其中将“ unpacksedges用作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]))

保持最小化