Python 将列表中的一个元素与另一个列表中的所有元素进行比较

Python 将列表中的一个元素与另一个列表中的所有元素进行比较,python,python-3.x,Python,Python 3.x,我有一个包含各种字母序列的列表 sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC'] 我想看看列表中每个序列的最后3个字母是否与所有其他序列的前3个字母匹配。如果发生这种情况,我想知道这两个序列的索引 我基本上是想制作一个邻接列表。下面是一个输入示例: >Sample_0 AAGTAAA >Sample_1 AAATGAT >Sample_2 AAAGTTT >Sam

我有一个包含各种字母序列的列表

sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']
我想看看列表中每个序列的最后3个字母是否与所有其他序列的前3个字母匹配。如果发生这种情况,我想知道这两个序列的索引

我基本上是想制作一个邻接列表。下面是一个输入示例:

>Sample_0
AAGTAAA
>Sample_1
AAATGAT
>Sample_2
AAAGTTT
>Sample_3
TTTTCCC
>Sample_4
AATTCGC
>Sample_5
CGCTCCC
以及输出:

>Sample_0 >Sample_1
>Sample_0 >Sample_2
>Sample_2 >Sample_3
>Sample_4 >Sample_5
现在,我尝试制作两个不同的列表,其中包含所有前缀和后缀,但我不知道这是否有帮助,以及如何使用它来解决我的问题

file = open("rosalind_grph2.txt", "r")

gene_names, sequences, = [], []
seq = ""

for line in file:
    if line[0] == ">":
        gene_names.append(line.strip())
        if seq == "":
            continue
        sequences.append(seq)
        seq = ""
    if line[0] in "ATCG":
        seq = seq + line.strip()
sequences.append(seq)

#So far I put all I needed into a list

prefix = [i[0:3] for i in sequences]
suffix = [i[len(i)-3:] for i in sequences]

#Now, all suffixes and prefixes are in lists as well
#but what now?  

print(suffix)
print(prefix)
print(sequences)
file.close

如果我正确理解了您的问题,那么此代码将在列表上枚举两次。它将第一个元素的最后3个字母与第二个元素的前3个字母进行比较,如果匹配,则打印元素的索引。如果这不是您想要的,请给出反馈/澄清。这是O(n^2),如果您进行初始传递并将索引存储在类似于字典的结构中,则可能会加快速度


for index1, sequence1 in enumerate(sequences):
    for index2, sequence2 in enumerate(sequences):
        if index1 != index2:
            if sequence1[-3:] == sequence2[0:3]:
                print(sequence1[-3:], index1, sequence2[0:3], index2)


如果我理解正确,您要做的是连接
序列的不同元素,其中连接是字符串的开头与另一个字符串的结尾匹配

使用
dict
的一种方法是使用以下函数
match\u head\u tail()

如果还想包括不匹配的序列,可以使用以下函数
match\u head\u tail\u all()


编辑1 如果您确实需要索引,请将上述内容与
enumerate()
结合使用以获取索引,例如:

def match_head_tail_all_indexes( items, length=3):
    return {
        i: [j for j, y in enumerate(items) if y[:length] == x[-length:]]
        for i, x in enumerate(items)}


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_all_indexes(sequences))
# {0: [1, 2], 1: [], 2: [3], 3: [], 4: [5], 5: []}

编辑2

如果您的输入包含了许多具有相同结尾的序列,您可能需要考虑实现一些缓存机制以提高计算效率(以内存效率为代价),例如:


编辑3 所有这些也可以仅通过
列表
实现,例如:

def match_head_tail_list(items, length=3):
    result = []
    for x in items:
        v = [y for y in items if y[:length] == x[-length:]]
        if v:
            result.append([x, v])
    return result


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_list(sequences))
# [['AAGTAAA', ['AAATGAT', 'AAAGTTT']], ['AAAGTTT', ['TTTTCCC']], ['AATTCGC', ['CGCTCCC']]]
甚至更少的筑巢:

def match_head_tail_flat(items, length=3):
    result = []
    for x in items:
        for y in items:
            if y[:length] == x[-length:]:
                result.append([x, y])
    return result


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_flat(sequences))
# [['AAGTAAA', 'AAATGAT'], ['AAGTAAA', 'AAAGTTT'], ['AAAGTTT', 'TTTTCCC'], ['AATTCGC', 'CGCTCCC']]

因此,如果你有两个不同3个字母的序列,那么没有一个序列匹配所有字母,对吗?请你(a)修复代码中的语法错误,并(b)提供一些玩具示例,其中包含提供的输入和预期的输出?从你的措辞来看,现在还不清楚你想做什么。@DanielMesejo是的,correct@norok2编辑,完成!我不太确定我是否理解如何解释输入和输出的符号。你能不能也用Python呢?如果我理解正确,您的输入与
序列
相同,您的输出告诉您序列的哪个元素与其他元素相关。对吗?谢谢。这在我的头脑中是有道理的。但是,如果我使用问题中的示例,它只匹配“AAA”。还有“TTT”和“CGC”要匹配。另外,我将每个元素的最后3个字母和所有元素的前3个字母进行比较。实际上,这段代码中有一个bug
enumerate(sequences)
此处返回一个生成器,该生成器将生成iterable的索引和元素。但它只能这样做一次。这意味着
的两个
碰撞在同一台发电机上。您需要使用
枚举(序列)
两次。另外,如果双
是多余的,请使用
将这两个条件组合成一个
如果
。谢谢你,我认为使用字典会对我的问题有所帮助。不过我到目前为止几乎没用过,所以我有点生疏了,我总是坚持列表。我得修改一下字典,谢谢!!另外,我没想到会使用如此复杂的列表理解;你永远不会停止学习:)@Axelio查看编辑。基本上,
dict
和额外的容器嵌套虽然合理,但都是相当可选的,您可以不使用。一般来说,
dict
将导致使用非数值访问数据的更高效、更简单的语法方法。容器嵌套将提高1对多关系的内存使用效率,因为“1”只出现一次。
sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_all(sequences))
# {'AAGTAAA': ['AAATGAT', 'AAAGTTT'], 'AAATGAT': [], 'AAAGTTT': ['TTTTCCC'], 'TTTTCCC': [], 'AATTCGC': ['CGCTCCC'], 'CGCTCCC': []}
def match_head_tail_all_indexes( items, length=3):
    return {
        i: [j for j, y in enumerate(items) if y[:length] == x[-length:]]
        for i, x in enumerate(items)}


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_all_indexes(sequences))
# {0: [1, 2], 1: [], 2: [3], 3: [], 4: [5], 5: []}
def match_head_tail_cached(items, length=3, caching=True):
    result = {}
    if caching:
        cached = {}
    for x in items:
        if caching and x[-length:] in cached:
            v = cached[x[-length:]]
        else:
            v = [y for y in items if y[:length] == x[-length:]]    
        if v:
            result[x] = v
    return result


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_cached(sequences))
# {'AAGTAAA': ['AAATGAT', 'AAAGTTT'], 'AAAGTTT': ['TTTTCCC'], 'AATTCGC': ['CGCTCCC']}
def match_head_tail_list(items, length=3):
    result = []
    for x in items:
        v = [y for y in items if y[:length] == x[-length:]]
        if v:
            result.append([x, v])
    return result


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_list(sequences))
# [['AAGTAAA', ['AAATGAT', 'AAAGTTT']], ['AAAGTTT', ['TTTTCCC']], ['AATTCGC', ['CGCTCCC']]]
def match_head_tail_flat(items, length=3):
    result = []
    for x in items:
        for y in items:
            if y[:length] == x[-length:]:
                result.append([x, y])
    return result


sequences = ['AAGTAAA', 'AAATGAT', 'AAAGTTT', 'TTTTCCC', 'AATTCGC', 'CGCTCCC']

print(match_head_tail_flat(sequences))
# [['AAGTAAA', 'AAATGAT'], ['AAGTAAA', 'AAAGTTT'], ['AAAGTTT', 'TTTTCCC'], ['AATTCGC', 'CGCTCCC']]