使用Python比较和丢弃列表中不符合特定条件的两个连续元素

使用Python比较和丢弃列表中不符合特定条件的两个连续元素,python,arrays,compare,elements,Python,Arrays,Compare,Elements,因此,我在下面展示了这个Python列表,为了简单起见,我将其命名为p: 我试图做的是比较连续对,然后只让元素具有相同的p[0]。在这个意义上,我们可以注意到p[0]=11,12,16,17,23,24,29,30的对将不存在,然后p将变成: [[13 9] [13 10] [14 8] [14 10] [15 7] [15 9] [18 2] [18 8] [19 1] [19 7] [20 1] [20 2] [21 2] [21 4] [

因此,我在下面展示了这个Python列表,为了简单起见,我将其命名为p:

我试图做的是比较连续对,然后只让元素具有相同的p[0]。在这个意义上,我们可以注意到p[0]=11,12,16,17,23,24,29,30的对将不存在,然后p将变成:

[[13  9]
 [13 10]
 [14  8]
 [14 10]
 [15  7]
 [15  9]
 [18  2]
 [18  8]
 [19  1]
 [19  7]
 [20  1]
 [20  2]
 [21  2]
 [21  4]
 [22  1]
 [22  3]
 [25  4]
 [25  6]
 [26  3]
 [26  5]
 [27  5]
 [27  6]
 [28  8]
 [28 10]
 [31  7]
 [31  9]
 [32  1]
 [32  2]
 [33  4]
 [33  6]
 [34  3]
 [34  5]] 

用python做这件事的方法是什么?如果有人能给我一个主意,我会很高兴的

假设输入列表名为lst,并且您希望全局删除第一个元素的项,则可以执行以下操作:

from collections import Counter
cnt = Counter(zip(*lst)[0])
result = [p for p in lst if cnt[p[0]] > 1]
print result
输出:

[[13, 9], [13, 10], [14, 8], [14, 10], [15, 7], [15, 9], [18, 2], [18, 8], [19, 1], [19, 7], [20, 1], [20, 2], [21, 2], [21, 4], [22, 1], [22, 3], [25, 4], [25, 6], [26, 3], [26, 5], [27, 5], [27, 6], [28, 8], [28, 10], [31, 7], [31, 9], [32, 1], [32, 2], [33, 4], [33, 6], [34, 3], [34, 5]]
但上面的代码确实不正确——我忽略了问题对连续性的要求。为了完整起见,让我写下假设正确的解决方案:

from itertools import groupby
from operator import itemgetter
result = []
for _, k in groupby(lst, itemgetter(0)):
    k = list(k)
    if len(k) > 1:
        result.extend(k)
print result
但是,对于这个特定示例,它们应该产生相同的结果。您应该使用更复杂的输入进行测试,例如

[[11,0],[11,0],[12,0],[13,0],[12,0],[13,0]]

只有第二种解决方案才能根据您的要求给出正确答案。

注意,原始问题是比较连续的对,然后只让元素具有相同的p[0],这意味着不应对原始列表进行排序。如果对原始列表进行了排序,则将拾取并保留不连续的对。虽然对示例列表进行了排序,但我不会假设是这样,因此这也将处理以下情况:

[[13, 5],
 [13, 2],
 [14, 9],
 [13. 6]]
产生

[[13, 5],
 [13, 2]]
为了让它更容易理解,我将展示一个简单的循环,但是列表理解可以让它更短。注意,计数器需要python 2.7

prev = None
newp = []
length = len(p) - 1
for i in range(length):
  if p[i][0] == p[i+1][0] or p[i][0] == prev:
    newp.append(p[i])
    prev = p[i][0]

if p[length][0] == p[length-1][0]:
  newp.append(p[length])

这将根据您的需要创建新列表

编写一个生成器,使其非常可读。您可以指定您正在做的事情:

def find_pairs(items):
    last = (None, None)
    for item in items:
        if item[0] == last[0]:
            yield last
            yield item
        last = item

print [x for x in find_pairs(p)]

使用列表理解的可能解决方案:

这个想法是向前和向后看,并选择是否有匹配。为避免边界情况下的索引器错误,请使用i>0和i 预加和附加伪值以避免处理索引器

使用zip获取下一个和上一个元素


然而,问题是只匹配连续的配对。这将与列表中的任何其他对匹配。这很有效。但我将用@sabbahillel在下面提出的代码测试他写的东西。非常感谢大家的回答。我学到了很多。这会挑选名单上的任何一对,而不是连续的一对matches@sabbahillel你能给我一个你认为失败的测试用例吗?对我来说它很好。例如,考虑元素1, 2和3通过匹配的情况。正确的结果是将元素1、2和3作为结果列表的开始。我认为您的代码将加倍元素2,因为第一次使用它时,元素1将是最后一个元素,元素2将是item。下一次元素3是项目,元素2是最后一次。因此,您将在答案列表中看到元素2两次。这与您如何理解“返回对”有关,如果3个连续元素匹配,则它们是2对。是的。每次提出问题时,似乎都会出现歧义,这可能会导致所需答案的差异。我想我们应该问@muammar,如果一行中有三个,他想看什么。你认为列表一定已经排序了吗?或者这只是一个例子。我给出了一个简单的循环,它允许一个未排序的列表和一个超过两对的匹配情况。对列表特征的限制允许使用更多更简单的解决方案。@sabbahillel我不这么认为,但我创建此列表的程序将始终以这种方式对其进行排序。请注意,第4行中有一个打字错误。它应该是p[i+1][0],而不是p[i+1]{0]。这也很有效。我得到的结果与@YS-L给出的答案完全相同。但是,如果我理解正确,这段代码会更基本,更适合不同的情况。因此,我稍后会选择正确的答案。我会测试更多。非常感谢!@muammar谢谢。修复
def find_pairs(items):
    last = (None, None)
    for item in items:
        if item[0] == last[0]:
            yield last
            yield item
        last = item

print [x for x in find_pairs(p)]
>>> ans = [el for i, el in enumerate(A) if (i > 0 and A[i-1][0] == el[0]) or \
(i < len(A)-1 and A[i+1][0] == el[0])]
>>> A = [[None, None]] + A + [[None, None]]
>>> ans = [el for i, el in enumerate(A) if A[i-1][0] == el[0] or \
A[i+1][0] == el[0]]
>>> A = [[None, None]] + A + [[None, None]]
>>> ans = [e2 for e1, e2, e3 in zip(A, A[1:], A[2:]) if e2[0] == e1[0] or \
e2[0] == e3[0]]