在Python中实现邻居以查找字符串的d-邻域

在Python中实现邻居以查找字符串的d-邻域,python,string,design-patterns,Python,String,Design Patterns,输入:一个字符串模式和一个整数d。 输出:字符串邻居的集合(模式,d) 示例输入: ACG 一, 示例输出: TCG ACG GCG CCG ACA 表演 阿格 AAG ATG 行政协调会 解决这个问题的算法是什么?这里有一个快速而肮脏的解决方案: chars = "ACGT" def neighbors(pattern, d): assert(d <= len(pattern)) if d == 0: return [pattern] r2

输入:一个字符串模式和一个整数d。 输出:字符串邻居的集合(模式,d)

示例输入:
ACG 一,

示例输出:
TCG ACG GCG CCG ACA 表演 阿格 AAG ATG 行政协调会


解决这个问题的算法是什么?

这里有一个快速而肮脏的解决方案:

chars = "ACGT"

def neighbors(pattern, d):
    assert(d <= len(pattern))

    if d == 0:
        return [pattern]

    r2 = neighbors(pattern[1:], d-1)
    r = [c + r3 for r3 in r2 for c in chars if c != pattern[0]]

    if (d < len(pattern)):
        r2 = neighbors(pattern[1:], d)
        r += [pattern[0] + r3 for r3 in r2]

    return r
请注意,这会给出在
d
位置上完全不同的邻居,而不是最多
d
位置。如果您想要后者(如示例输出所示),您可以简单地组合
d
的不同值的结果,如下所示:

def neighbors2(pattern, d):
    return sum([neighbors(pattern, d2) for d2 in range(d + 1)], [])
以下是一些示例输出:

>>> neighbors("ACG", 1)
['CCG', 'GCG', 'TCG', 'AAG', 'AGG', 'ATG', 'ACA', 'ACC', 'ACT']
>>> neighbors2("ACG", 1)
['ACG', 'CCG', 'GCG', 'TCG', 'AAG', 'AGG', 'ATG', 'ACA', 'ACC', 'ACT']

这里有一个快速而肮脏的解决方案:

chars = "ACGT"

def neighbors(pattern, d):
    assert(d <= len(pattern))

    if d == 0:
        return [pattern]

    r2 = neighbors(pattern[1:], d-1)
    r = [c + r3 for r3 in r2 for c in chars if c != pattern[0]]

    if (d < len(pattern)):
        r2 = neighbors(pattern[1:], d)
        r += [pattern[0] + r3 for r3 in r2]

    return r
请注意,这会给出在
d
位置上完全不同的邻居,而不是最多
d
位置。如果您想要后者(如示例输出所示),您可以简单地组合
d
的不同值的结果,如下所示:

def neighbors2(pattern, d):
    return sum([neighbors(pattern, d2) for d2 in range(d + 1)], [])
以下是一些示例输出:

>>> neighbors("ACG", 1)
['CCG', 'GCG', 'TCG', 'AAG', 'AGG', 'ATG', 'ACA', 'ACC', 'ACT']
>>> neighbors2("ACG", 1)
['ACG', 'CCG', 'GCG', 'TCG', 'AAG', 'AGG', 'ATG', 'ACA', 'ACC', 'ACT']

添加更多信息(什么是“邻居”?等等),并向我们展示您到目前为止所做的。“解决这个问题的算法是什么?”“看起来它是在遗传密码子上运行的,目标是找到所有在
d
氨基酸方面完全不同的密码子。@TomKarzes:您是说“碱基”?;)@Pier实际上我应该说核苷酸。添加更多的信息(什么是“邻居”?等等),并向我们展示你到目前为止所做的。“解决这个问题的算法是什么?”“看起来它是在遗传密码子上运行的,目标是找到所有在
d
氨基酸上完全不同的密码子。@TomKarzes:你是说“碱基”?)@Pier实际上我应该说核苷酸。我不明白r2在代码中是什么意思?我使用
r2
作为临时变量来保存递归调用的结果。有两种情况:(1)在尾部改变
d-1
条目,然后在返回时改变第一个条目;(2)如果字符串的尾部足够长,则在尾部改变
d
条目。然后在顶层调整递归调用的结果,以在结果列表
r
中创建新条目。非常感谢。最后一个问题,对于ACG和1个示例,“r2=邻居(模式[1:],d-1),r=[c+r3表示r2中的r3表示字符中的c,如果c!=模式[0]]”。r3=r2是否等于CG,因为d-1=0,核苷酸没有变化?@汤姆Karzes@nosense在您提到的示例中,
pattern
ACG
,因此
pattern[1:
“CG”
d-1
0
。因此递归调用的返回值只是一个包含单个字符串的列表,即在这种情况下,
r2
[“CG”]
。然后在下面的语句中,
r3
接受列表中的单个值,即
“CG”
。唯一的区别是,
r2
是一个包含单个元素的列表,而
r3
接受该元素的值。@Tom Karzes现在我了解了“ACG”、“CCG”、“GCG”、“TCG”、“AAG”、“AGG”、“ATG”是如何产生的。如果我理解正确,最后一轮的G被A、C或T替换,然后模式[0]=C(此时模式为CG),因此我们通过r+=[r2中r3的模式[0]+r3]得到CA、CC或CT。我很好奇第一个A是如何添加到CA、CC或CT的?我不明白r2在代码中是什么意思?我使用
r2
作为临时变量来保存递归调用的结果。有两种情况:(1)在尾部改变
d-1
条目,然后在返回时改变第一个条目;(2)如果字符串的尾部足够长,则在尾部改变
d
条目。然后在顶层调整递归调用的结果,以在结果列表
r
中创建新条目。非常感谢。最后一个问题,对于ACG和1个示例,“r2=邻居(模式[1:],d-1),r=[c+r3表示r2中的r3表示字符中的c,如果c!=模式[0]]”。r3=r2是否等于CG,因为d-1=0,核苷酸没有变化?@汤姆Karzes@nosense在您提到的示例中,
pattern
ACG
,因此
pattern[1:
“CG”
d-1
0
。因此递归调用的返回值只是一个包含单个字符串的列表,即在这种情况下,
r2
[“CG”]
。然后在下面的语句中,
r3
接受列表中的单个值,即
“CG”
。唯一的区别是,
r2
是一个包含单个元素的列表,而
r3
接受该元素的值。@Tom Karzes现在我了解了“ACG”、“CCG”、“GCG”、“TCG”、“AAG”、“AGG”、“ATG”是如何产生的。如果我理解正确,最后一轮的G被A、C或T替换,然后模式[0]=C(此时模式为CG),因此我们通过r+=[r2中r3的模式[0]+r3]得到CA、CC或CT。我很好奇第一个A是如何添加到CA、CC或CT的?