[英]Finding common elements of a list based on some criteria?
The input is in form of a list of tuples,输入是元组列表的形式,
left_corners = [((380, 456), 1), ((1129, 456), 2), ((354, 328), 3), ((1137, 325), 4)]
right_corners = [((784, 456), 1), ((1535, 456), 2), ((778, 328), 3)]
The common elements would be the ones which have the second element of the tuple as 1, 2, 3
so I would want the final representation to look like -共同元素将是元组的第二个元素为
1, 2, 3
所以我希望最终表示看起来像 -
[(((380, 456), 1),((784, 456), 1)), (((1129, 456), 2),((1535, 456), 2)), (((354, 328), 3), ((778, 328), 3))]
I can't think of a solution without a few loops (looping over both the elements and appending the elements which have the same second element in a common list).我想不出没有几个循环的解决方案(循环两个元素并在公共列表中附加具有相同第二个元素的元素)。 Is there a more pythonic way?
有没有更蟒蛇的方式? I am open to other representations of this in numpy or something too.
我对 numpy 或其他内容的其他表示持开放态度。
Assumptions: We can assume both lists are sorted with the key being the second element of the list, but either left_corners
or right_corners
might have more elements than the other假设:我们可以假设两个列表都是排序的,键是列表的第二个元素,但是
left_corners
或right_corners
可能比另一个有更多的元素
If you use dictionaries, you could do something a bit more efficient如果你使用字典,你可以做一些更有效率的事情
group_lists = {}
for corner in (left_corners+right_corners):
group_lists[corner[1]] = group_lists.get(corner[1], [])
group_lists[corner[1]].append(corner)
output = [group_lists[k] for k in group_lists]
And if you want your output to be a list of tuples instead of a list of lists you would just have to change that last line to如果您希望 output 成为元组列表而不是列表列表,则只需将最后一行更改为
output = [tuple(group_lists[k]) for k in group_lists]
first, second = (left_corners, right_corners) if len(left_corners) > len(right_corners) else (right_corners, left_corners)
[(i, j) for i in first for j in second if i[1] == j[1]]
I assumed that the second element (key to unify the tuples) can be anything not just 1, 2, 3
我假设第二个元素(统一元组的关键)可以是任何东西
1, 2, 3
Another assumption is that the second element is sorted but can skip numbers for example, if this is not the case, then zip
is the way to go.另一个假设是第二个元素已排序但可以跳过数字,例如,如果不是这种情况,那么
zip
是 go 的方式。
left_corners = [(X, 1), (Y, 2), (Z, 3)]
right_corners = [(A, 1), (B, 3)]
Maybe (not sure, as the problem is not very clearly stated) this is what you want:也许(不确定,因为问题没有很清楚地说明)这就是你想要的:
good_corners = [ [ t for t in corners if t[1] in {1,2,3}] for corners in (left_corners, right_corners) ]
result = list(zip(*good_corners))
How about a list comprehension?列表理解怎么样?
a = [k for k in left_corners if k[1] in [1,2,3]] + [k for k in right_corners if k[1] in [1,2,3]]
output: output:
[((380, 456), 1), ((1129, 456), 2), ((354, 328), 3), ((784, 456), 1), ((1535, 456), 2), ((778, 328), 3)]
This is only valid, if the ordering is irrelevant.这仅在排序无关时才有效。 If it needs to have the order you can sort using a lambda function:
如果需要排序,您可以使用 lambda function 进行排序:
sorted(a, key=lambda x: x[1])
output: output:
[((380, 456), 1), ((784, 456), 1), ((1129, 456), 2), ((1535, 456), 2), ((354, 328), 3), ((778, 328), 3)]
This worked pretty well for me这对我来说效果很好
combined_list = list(zip(left_corners, right_corners))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.