如何改进评估列表以确定它是不是包含特定连续项目的方法?

Posted

技术标签:

【中文标题】如何改进评估列表以确定它是不是包含特定连续项目的方法?【英文标题】:How can method which evaluates a list to determine if it contains specific consecutive items be improved?如何改进评估列表以确定它是否包含特定连续项目的方法? 【发布时间】:2019-08-16 08:05:17 【问题描述】:

我有一个包含数千万个列表的嵌套列表(我也可以使用元组)。每个列表长 2-7 项。列表中的每个项目都是 1-5 个字符的字符串,并且每个列表不超过一次。 (为简单起见,我在下面的示例中使用单个字符项)

#Example nestedList: 

nestedList = [
    ['a', 'e', 'O', 'I', 'g', 's'],
    ['w', 'I', 'u', 'O', 's', 'g'],
    ['e', 'z', 's', 'I', 'O', 'g']
]

我需要找出我的嵌套列表中的哪些列表包含一对项目,这样我就可以对这些列表做一些事情而忽略其余的。这需要尽可能高效。

我正在使用以下函数,但它看起来很慢,我只知道必须有更聪明的方法来做到这一点。

def isBadInList(bad, checkThisList):
    numChecks = len(list) - 1
    for x in range(numChecks):
        if checkThisList[x] == bad[0] and checkThisList[x + 1] == bad[1]:
            return True
        elif checkThisList[x] == bad[1] and checkThisList[x + 1] == bad[0]:
            return True
    return False

我会这样做的,

bad = ['O', 'I']

for checkThisList in nestedLists:
    result = isBadInList(bad, checkThisList)
    if result:
        doStuffToList(checkThisList)

#The function isBadInList() only returns true for the first and third list in nestedList and false for all else.

如果可能的话,我需要一种方法来更快地做到这一点。我可以使用元组而不是列表,或者任何它需要的东西。

【问题讨论】:

(1) 我假设字符串项不都是一个字符长? (2) 您是否计划经常针对相同的 nestedLists 值和不同的 bad 运行此操作,反之亦然,还是每次运行时一切都不同? (3) 大致有多少种不同的字符串项? 见Checking if list is a sublist。 每个字符串项的长度为 1 - 5 个字符。另外,对于未来,我正在考虑将字符串项切换为整数,这将代表唯一的字符串项。 我有点作弊来解决我的问题。我找到了一种将项目对表示为整数的方法。所以现在我可以简单地使用:is intX in listY. 【参考方案1】:
nestedList = [
    ['a', 'e', 'O', 'I', 'g', 's'],
    ['w', 'I', 'u', 'O', 's', 'g'],
    ['e', 'z', 's', 'I', 'O', 'g']
]

#first create a map
pairdict = dict()


for i in range(len(nestedList)):
    for j in range(len(nestedList[i])-1):
        pair1 = (nestedList[i][j],nestedList[i][j+1])
        if pair1 in pairdict:
            pairdict[pair1].append(i+1)
        else:
            pairdict[pair1] = [i+1]
        pair2 = (nestedList[i][j+1],nestedList[i][j])
        if pair2 in pairdict:
            pairdict[pair2].append(i+1)
        else:
            pairdict[pair2] = [i+1]

del nestedList

print(pairdict.get(('e','z'),None))

创建一个值对并将它们存储到映射中,键是对,值是索引,然后删除你的列表(这可能会占用太多内存), 然后,您可以利用 dict 进行查找,并打印值出现的索引。

【讨论】:

【参考方案2】:

我认为你可以在这里使用一些regex 来加快速度,尽管它仍然是一个顺序操作,所以你最好的情况是O(n) 使用这种方法,因为你必须遍历每个列表,但是因为我们有遍历每个子列表,使其成为O(n^2)

import re

p = re.compile('[OI]2|[IO]2') # match only OI or IO

def is_bad(pattern, to_check): 
    for item in to_check:
        maybe_found = pattern.search(''.join(item))
        if maybe_found:
            yield True
        else:
            yield False


l = list(is_bad(p, nestedList))

print(l)
# [True, False, True]

【讨论】:

以上是关于如何改进评估列表以确定它是不是包含特定连续项目的方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 Pandas 列是不是包含特定值

如何从对象数组中获取具有属性的列表,除非它包含具有特定值的另一个项目?

如何改进此 LINQ 查询以查找用户将列表中的所有技能

Swift:确定自定义对象数组是不是包含特定字符串[重复]

如何测试一个列表是不是包含另一个列表作为连续子序列?

如何使用 XMPP 实现聊天列表