如何使用Python根据下一步的需求过滤列表



列表只包含整数。我需要选择具有下一个需求的元素(每个需求都是一个单独的问题(:

  1. 1和1之间的元素:[2,1,3,1,3] -> [3][2,1,3,4,1,3] -> [3,4]

  2. 相同数字之间的元素:a(只允许一对相同数字:[1,2,3,2] -> [3] (2 and 2), [1,4,3,5,4] -> [3,5], (4 and 4)b( 允许多对:[1,2,1,2] -> [[2],[1]], (pairs of: (1,1),(2,2)); [1,4,3,5,4,3,2] -> [[3,5],[5,4], (pairs of: (4,4), (3,3))

  3. 具有多个相同邻域的元素:[1,1,3] -> [1,1], (2 consecutive 1s), [1,1,3,2,2,2,1] -> [1,1,2,2,2] (2 consecutive 1s and 3 consecutive 2s)

解决这个问题的一般方法是什么?我使用过过滤器,但只有一个参数谓词:filter(lambda x: (x%2 == 0), numbers)

是否有其他方法而不是嵌套循环?也许更实用的风格。有可能使用卷积作为解决方案吗?

对于Q1,您可以创建一个索引为1s的列表,并再次迭代该列表以查找1之间的项。

ones = [i for i,x in enumerate(lst) if x==1]
for i,j in zip(ones, ones[1:]):
    print(lst[i+1:j])

输出:

[2,1,3,1,3]   -> [3]
[2,1,3,4,1,3] -> [3, 4]

对于Q2,类似于Q1,对列表进行迭代以找到项目的索引,并将它们保存在字典中。然后对其进行迭代,找到多次出现的数字,并打印出这些数字之间的项目:

d = {}
for i,x in enumerate(lst):
    d.setdefault(x, []).append(i)
for k,indices in d.items():
    if len(indices)>1:
        for i,j in zip(indices, indices[1:]):
            print(lst[i+1:j])

输出:

[1,2,3,2]   -> [3]
[1,4,3,5,4] -> [3, 5]

以下是使用itertools的Q1/Q3和使用经典循环的Q2的解决方案:

Q1

这一组按等于1分组,然后删除第一组和最后一组(1或不是1,但在任何情况下我们都不想保留(,然后删除等于1的组,只留下内部组。

l1 = [2,1,3,4,1,3,6,1,0]
from itertools import groupby, chain
list(chain.from_iterable(g for k,g in
                         [(k,list(g)) for k,g in
                          groupby(l1, lambda x: x==1)][1:-1]
                         if not k))
# [3, 4, 3, 6]
第三季度

在这里,我们按相同的连续值进行分组,如果大于1,则使用组长度进行过滤。

注意。如果一个值出现2次以上,就会产生副作用,在这种情况下,预期行为应该明确

l3 = [1,1,3,2,2,2,1]
from itertools import groupby, chain
list(chain.from_iterable(l for k,g in groupby(l3) if len(l:=list(g))>1))
# [1, 1, 2, 2, 2]
第二季度

对于这个,我们首先阅读列表以识别重复的值。然后,我们再次读取该列表,并在遇到一次关键字后,将该值添加到一个以重复项为关键字的列表字典中。

l2 = [1,4,3,5,4,3,2]
from collections import Counter
dups = {k: [] for k,v in Counter(l2).items() if v>1}
active = set()
for i in l2:
    if i in dups: # if many keys are expected initialize and use a set of the keys to improve efficiency
        active.remove(i) if i in active else active.add(i)
    for k in active:
        if i != k:
            dups[k].append(i)
list(dups.values())
# [[3, 5], [5, 4]]

使用itertools.groupby 可以在不嵌套for循环的情况下解决第3部分

from itertools import groupby
def repeating_sections(lst):
    out_lst = []
    for key, group in groupby(lst):
        _lst = list(group)
        if len(_lst) > 1:
            out_lst += _lst
    return out_lst
print(repeating_sections([1, 1, 3, 2, 2, 2, 1]) 
# [1, 1, 2, 2, 2]

也许你可以创建一个函数?它符合的所有三个标准

def filterNumbers(numList, targetNum) -> list:
firstPosition = numList.index(targetNum)
lastPosition = numList.index(targetNum, firstPosition + 2)
while True:
    try:
        if lastPosition != (len(numList)-1):
            if numList[lastPosition] == numList[lastPosition+1]:
                lastPosition = lastPosition + 1
                continue
        break
    except Exception as e:
        print(e)
resultList = numList[firstPosition+1:lastPosition]
return resultList

条件1:

test1 = [2, 1, 3, 1, 3]
filterNumbers(test1, 1)
#Output:
[3]

条件2:

test2 = [1, 4, 3, 5, 4]
filterNumbers(test2, 4)
#Output:
[3, 5]

条件3:

test3 = [1,1,3,2,2,2,1]
filterNumbers(test3, 1)
#Output
[1, 3, 2, 2, 2]

我假设你在写第三个条件时有一个拼写错误,因为你跳过了3,包括了前一个1。

最新更新