Python 将列表与保留顺序的元素的其他列表进行比较

Python 将列表与保留顺序的元素的其他列表进行比较,python,Python,我有几张单子。一些列表彼此共享常用词。我试着看看每个列表中,还有哪些列表中有相同顺序的常用词。例如,假设这些是我的列表(为了简单起见,使用字母代替单词/字符串): 在这里,我们可以看到列表1中的[a,b]在列表2和列表4中也按顺序出现。我们还可以看到清单3中的[f,g]出现在清单4中。因此,我们将这些列表相互映射如下: list1: list2, list4 #(contains [a,b]) list2: list1, list4 #(contains [a,b]) list3: list4

我有几张单子。一些列表彼此共享常用词。我试着看看每个列表中,还有哪些列表中有相同顺序的常用词。例如,假设这些是我的列表(为了简单起见,使用字母代替单词/字符串):

在这里,我们可以看到列表1中的[a,b]在列表2和列表4中也按顺序出现。我们还可以看到清单3中的[f,g]出现在清单4中。因此,我们将这些列表相互映射如下:

list1: list2, list4 #(contains [a,b])
list2: list1, list4 #(contains [a,b])
list3: list4 #(contains [f,g])
list4: list1, list2, list3 #(contains [a,b] and [f,g])
您可以忽略注释,因为这是为了解释,它将只是相互映射的列表名称。请注意,即使list2包含元素“f”和“g”,因为它们的顺序不是[f,g],所以它也不会映射到list3或list4

我已经使用set.intersection()编写了一个函数来获取所有列表中的常用词,但它不考虑顺序。因此,我似乎无法确定使用哪种数据结构或算法来以这种方式将列表相互映射

我尝试了以下方法,其中WordList是我的列表列表,每个列表包含各自的字数:

filelist = {}
for i in range(0, len(wordlists)):
    current_wordlist = wordlists[i]
    for j, j_word in enumerate(current_wordlist):
        if current_wordlist[j] == j_word:
            if j_word not in filelist:
                filelist[i] = {j}
            else:
                filelist[i].append(j)
但是它没有正确映射,因为它没有映射到正确的列表号。我希望你能给我一些反馈或者其他一些检查的技巧


如何实现这一点?

首先,我将创建一个帮助器,为每个列表创建一组连续项:

def create_successive_items(lst, n):
    return set(zip(*[lst[i:] for i in range(n)]))
然后,您只需根据以下集合检查所有列表的交点:

list1 = ['a','b','c','d']
list2 = ['f','n','a','b','g']
list3 = ['x','f','g','z']
list4 = ['y','a','b','f','g','k']


lists = [list1, list2, list3, list4]

# First look for two elements
i = 2

all_found = []

while True:
    # find all "i" successive items in each list as sets
    succ = [create_successive_items(lst, i) for lst in lists]
    founds = []
    # Check for matches in different lists
    for list_number1, successives1 in enumerate(succ, 1):
        # one only needs to check all remaining other lists so slice the first ones away
        for list_number2, successives2 in enumerate(succ[list_number1:], list_number1+1):
            # Find matches in the sets with intersection
            inters = successives1.intersection(successives2)
            # Print and save them
            if inters:
                founds.append((inters, list_number1, list_number2))
                print(list_number1, list_number2, inters)

    # If we found matches look for "i+1" successive items that match in the lists
    # One could also discard lists that didn't have "i" matches, but that makes it
    # much more complicated.
    if founds:
        i += 1
        all_found.append(founds)
    # no new found, just end it
    else:  
        break
这将打印匹配项:

1 2 {('a', 'b')}
1 4 {('a', 'b')}
2 4 {('a', 'b')}
3 4 {('f', 'g')}
这些文件也可在
所有文件中找到,并且可以使用和/或转换,即转换为
目录

matches = {}
for match, idx1, idx2 in all_found[0]:
    matches.setdefault(idx1, []).append(idx2)
    matches.setdefault(idx2, []).append(idx1)

>>> matches
{1: [2, 4], 
 2: [1, 4], 
 3: [4], 
 4: [1, 2, 3]}

通过使用元组集,您可以获得一些乐趣。因为元组是可散列的,所以您只需要两个帮助函数就可以从给定列表中获得所有连续的有序子列表,并且可以使用集合交集进行比较

from itertools import permutations
def radix(rg, n_len):
    """
    Returns all ordered sublists of length n_len from
    the list rg
    :type rg: list[char]
    :type n_len: int
    """
    for x in range(0, len(rg) - n_len + 1):
        yield tuple(rg[x:x + n_len])

def all_radixes(rg):
    """
    Returns all ordered sublists of length 2 or longer
    from the given list
    :type rg: list[char]
    """
    for x in range(2, len(rg) + 1):
        for result in radix(rg, x):
            yield result

def compare_lists(rg1, rg2):
    s1 = set(all_radixes(rg1))
    s2 = set(all_radixes(rg2))
    return s1 & s2

list1 = 'a,b,c,d'.split(',')
list2 = 'f,n,a,b,g'.split(',')
list3 = 'x,f,g,z'.split(',')
list4 = 'y,a,b,f,g,k'.split(',')

all_lists = [ list1, list2, list3, list4 ]
for z in permutations(all_lists, 2):
    print 'Intersection of %s and %s: %s' % (z[0], z[1], compare_lists(z[0], z[1]),)

顺便说一句:
set(x代表所有半径的x(rg1))
set(所有半径的x(rg1))
是相同的。谢谢。难道我们不能将所有的_founds声明为dict并让它映射值吗?如1->2,4;2 -> 4; 3->4,4->1,2,3?这不是问题,但是答案已经很长了,所以我不想包含太多的逻辑。您始终可以在函数之后操作
所有
。我想我知道了,我只是在检查它是否能保持秩序时遇到了麻烦。大多数形式的intersect都不考虑顺序,我不确定列表或集合中是否存在这样的函数。非常感谢你!
from itertools import permutations
def radix(rg, n_len):
    """
    Returns all ordered sublists of length n_len from
    the list rg
    :type rg: list[char]
    :type n_len: int
    """
    for x in range(0, len(rg) - n_len + 1):
        yield tuple(rg[x:x + n_len])

def all_radixes(rg):
    """
    Returns all ordered sublists of length 2 or longer
    from the given list
    :type rg: list[char]
    """
    for x in range(2, len(rg) + 1):
        for result in radix(rg, x):
            yield result

def compare_lists(rg1, rg2):
    s1 = set(all_radixes(rg1))
    s2 = set(all_radixes(rg2))
    return s1 & s2

list1 = 'a,b,c,d'.split(',')
list2 = 'f,n,a,b,g'.split(',')
list3 = 'x,f,g,z'.split(',')
list4 = 'y,a,b,f,g,k'.split(',')

all_lists = [ list1, list2, list3, list4 ]
for z in permutations(all_lists, 2):
    print 'Intersection of %s and %s: %s' % (z[0], z[1], compare_lists(z[0], z[1]),)