使用递归遍历列表

时间:2019-04-21 21:27:55

标签: python recursion

我正在尝试使用递归比较两个列表之间的元素值。对于索引iif list1[i] = A and list2[i] = T,反之亦然,这些值有效。同样,对于索引i,if list1[i] = G and list2[i] = C,反之亦然,这些值均有效。但是,如果不满足这两个条件(list1[i] = A and list2[i] = G),则该值无效。我创建了两个新列表,其中存储了有效值,并将无效值替换为空白''。

此代码可与for循环(for i in range (0, len(list1)):)配合使用,但是如何使用递归?

def check_valid(sequence1, sequence2):

 sequence1 = list(sequence1)

 sequence2 = list(sequence2)

 valid_units1 = []

 valid_units2 = []

    if (sequence1[i] == 'A' and sequence2[i] == 'T') or (sequence1[i] == 'T' and sequence2[i] == 'A'):
        valid_units1.append(sequence1[i])
        valid_units2.append(sequence2[i])
    elif (sequence1[i] == 'G' and sequence2[i] == 'C') or (sequence1[i] == 'C' and sequence2[i] == 'G'):
        valid_units1.append(sequence1[i])
        valid_units2.append(sequence2[i])
    else:
        valid_units1.append(' ')
        valid_units2.append(' ')

    print(valid_units1)
    print(valid_units2)

    valid_units = [valid_units1, valid_units2]
    return valid_units

2 个答案:

答案 0 :(得分:1)

如果您从两个列表开始,并且想要逐个比较它们,则可以使用zip()来简化生活。它将使您恢复配对的元素。因此,如果您从两个列表开始,则可以zip

list1 = ['A', 'T']
list2 = ['C', 'G']

zipped = list(zip(list1, list2))
# zipped is [('A', 'C'), ('T', 'G')]

#or use a list comprehension:
zipped = [pair for pair in  zip(list1, list2)]

zip()返回一个迭代器,这就是将其包装在上面的list()中的原因。如果您在循环中或其他需要使用插入器的情况下使用它,则无需这样做。

如果要比较这些字母,可以使用一个字典,该字典定义哪个字母映射到另一个字母,这将使您编写一个更简单的测试函数:

# Define a mapping that describes which elements belong togethre
pairs = {
    'G':'T',
    'T':'G',
    'C':'A',
    'A':'C'
}

list1 = ['A', 'A', 'T', 'C', 'G', 'C', 'T', 'A']
list2 = ['C', 'G', 'G', 'A', 'C', 'A', 'C', 'T']

# make a new list if the pairs line up with the mapping:
legal = [(a, b) for a, b in  zip(list1, list2) if pairs[a] == b ]

# legal pairs: [('A', 'C'), ('T', 'G'), ('C', 'A'), ('C', 'A')]

没有太多理由递归执行此操作,但是您当然可以。由于zip()返回一个迭代器(下面的pairs),因此您可以在其上调用next()到达下一个值,然后将迭代器传递回去。缺项时将引发StopIteration错误,因此可能是递归的边缘条件:

def buildList(pairs, mapping):
    ''' Takes an iterator and mapping, returns a list of legal items defined by mapping '''
    try:
        a_pair = next(pairs)  # get first item from zipped list
    except StopIteration:   # no more items, just return an empty list
        return []

    a, b = a_pair            
    if mapping[a] == b:    
        return [(a, b)] + buildList(pairs, mapping)
    else: 
        return buildList(pairs, mapping)


list1 = ['A', 'A', 'T', 'C', 'G', 'C', 'T', 'A']
list2 = ['C', 'G', 'G', 'A', 'C', 'A', 'C', 'T']
pairs = {'G':'T','T':'G','C':'A','A':'C'}

buildList(zip(list1, list2), pairs) # use zip to make the zipped iterator

答案 1 :(得分:0)

此问题带有递归标签,这是我的看法-

subcription

这很直观,但是与def head(xs = []): return xs[0] def tail(xs = []): return xs[1:] def check_pair(x = "", y = "", swap = True): if x == "A" and y == "C": return True elif x == "G" and y == "T": return True else: return swap and check_pair(y, x, False) def check_valid(a = [], b = []): if (not a) or (not b): return elif check_pair(head(a), head(b)): yield (head(a), head(b)) yield from check_valid(tail(a), tail(b)) else: yield from check_valid(tail(a), tail(b)) a = ['A', 'A', 'T', 'C', 'G', 'C', 'T', 'A'] b = ['C', 'G', 'G', 'A', 'C', 'A', 'C', 'T'] print(list(check_valid(a,b))) # [('A', 'C'), ('T', 'G'), ('C', 'A'), ('C', 'A')] 类似,zip函数创建中间值。我们可以使用简单的索引tail-

来减少内存需求
i

您可能对此related Q&A

感兴趣