简体   繁体   English

根据某些标准查找列表的共同元素?

[英]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_cornersright_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM