Python-str映射置换中使用递归的一些限制和特殊条件

2024-09-27 22:09:16 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个字符串作为输入,我需要将a改为t,c改为g,u改为a,g改为c[a-t,c-g,g-c,u-a]。另一个特殊条件是,最多可以有两个实例,其中u's转换为g's和/或g's转换为t's[u-g,g-t]。你知道吗

举个例子-

input : 
    auugca
output : 
    taacgt
    tgacgt
    taatgt
    tggcgt
    tgatgt
    tagtgt

在输出中

  1. 无特殊变化
  2. 将第2个字符u特殊更改为g
  3. 将第3个字符u特殊更改为g
  4. 将第4个字符g特殊更改为t
  5. 两个特殊的变化第二和第三字符
  6. 第二和第四个字符的两个特殊变化
  7. 第三和第四个字符的两个特殊变化

我是这样想的

  • 从字符串的开头开始
  • 转换a-t和c-g
  • 如果发现u或g,检查之前有多少特价商品 遇到,如果少于两个,则视为特殊,递增 以前遇到的计数器,从字符串的下一个位置递归地创建两个新的搜索一个带有特殊考虑,另一个没有

我想到的代码是(在Python中)-

 # mirna is the string to be converted
 # wobblecount is the number of specials coneverted
 # location is from which location of the string the convertion will start
 # compliment is the end string to be created


 def createonewobble(mirna, location, wobblecount, compliment):

    for counter in range(location, len(mirna)):
        if (mirna[counter] == 'A' or mirna[counter] == 'a'):
            compliment = compliment + "t"
        elif (mirna[counter] == 'C' or mirna[counter] == 'c'):
            compliment = compliment + "g"
        elif ((mirna[counter] == 'U' or mirna[counter] == 'u') and (wobblecount < 2)):
            compliment = compliment + "g"
            createonewobble(mirna, counter+1 , wobblecount+1, compliment)
            compliment = compliment + "a"
            createonewobble(mirna, counter+1 , wobblecount, compliment)
        elif ((mirna[counter] == 'G' or mirna[counter] == 'g') and (wobblecount < 2)):
            compliment = compliment + "t"
            createonewobble(mirna, counter+1 , wobblecount+1, compliment)
            compliment = compliment + "a"
            createonewobble(mirna, counter+1 , wobblecount, compliment)
        elif ((mirna[counter] == 'U' or mirna[counter] == 'u') and (wobblecount == 2)):
            compliment = compliment + "a"
        elif ((mirna[counter] == 'G' or mirna[counter] == 'g') and (wobblecount == 2)):
            compliment = compliment + "c"

    print compliment


mirna = "auugca"
createonewobble(mirna, 0, 0, "")

输出

tggcgt
tggatgt
tggatagt
tggatagt
tggatgt
tggatagt
tggatagt
tgagtgt
tgagtagt
tgagtagt
tgagatgt
tgagatagt
tgagatagt
tgagatgt
tgagatagt
tgagatagt
tgagtgt
tgagtagt
tgagtagt
tgagatgt
tgagatagt
tgagatagt
tgagatgt
tgagatagt
tgagatagt

这是给我25个输出,没有一个正确的一个,也有一些长度远远超过字符串的大小。我哪里出错了?你知道吗


Tags: orandthe字符串iscounterlocationelif
1条回答
网友
1楼 · 发布于 2024-09-27 22:09:16

这里要解决的问题是一种带回溯的递归,有一些限制。你知道吗

您的代码接近解决方案,但:

  1. 它不是Python,所以很难理解。下次提高你的可读性。你知道吗
  2. 在处理排列问题时,应该使用set来避免重复。在您的解决方案中,您使用了print,这将为您提供重复打印(如果有)。你知道吗
  3. 最重要的是调用递归函数时,传递给它的compliment变量以前修改过,现在不再有效。你知道吗

要解释第3点,让我们看看您的代码:

elif ((mirna[counter] == 'G' or mirna[counter] == 'g') and (wobblecount < 2)):
        compliment = compliment + "t"
        createonewobble(mirna, counter+1 , wobblecount+1, compliment)
        compliment = compliment + "a"
        createonewobble(mirna, counter+1 , wobblecount, compliment)

例如,假设到目前为止compliment = X,您第一次用compliment = Xt调用createonewobble,第二次用compliment = Xta调用createonewobble,我肯定这不是您想要的。你知道吗

有效解决方案:

def create_one_wobble(options, mirna, wobble_count, compliment):

    mirna = mirna.lower()

    if wobble_count == 2:
        for letter in mirna:
            if letter == 'a':
                compliment += 't'
            elif letter == 'c':
                compliment += 'g'
            elif letter == 'g':
                compliment += 'c'
            else:
                compliment += 'a'
        options.append(compliment)

    else:
        for index, letter in enumerate(mirna):
            if letter == 'a':
                compliment += 't'
            elif letter == 'c':
                compliment += 'g'
            elif letter == 'g':
                create_one_wobble(options, mirna[index+1:], wobble_count + 1, compliment + "t")
                create_one_wobble(options, mirna[index+1:], wobble_count + 1, compliment + "c")
                compliment += 'c'
            elif letter == 'u':
                create_one_wobble(options, mirna[index+1:], wobble_count + 1, compliment + "g")
                create_one_wobble(options, mirna[index+1:], wobble_count + 1, compliment + "a")
                compliment += 'a'

permutations = []
mirna = "auugca"
create_one_wobble(permutations, mirna, 0, "")
permutations = sorted(list(set(permutations)))
for a in permutations:
    print(a)

打印输出:

taacgt
taatgt
tagcgt
tagtgt
tgacgt
tgatgt
tggcgt

编辑:

关于第1点。 很明显(至少对我来说)你有一些编程方面的背景,算法和函数的概念对你来说并不完全陌生。你知道吗

尽管如此,很明显您对Python还有些陌生。你知道吗

Python应该是一种易于编写、易于理解的语言。 “pythonic代码”是利用Python标准库的强大功能编写的尽可能简单的代码。你知道吗

  1. 了解Python中的类型。

    for counter in range(location, len(mirna)):
    

    这行代码使用索引对字符串进行迭代。在Python中 字符串已经是iterable对象。那意味着你可以 这是:

    for letter in word:
    

    假设word是一个字符串,一切都会按计划进行。

  2. 可读性。

    if (mirna[counter] == 'A' or mirna[counter] == 'a'):
    

    这行代码用于确定mirna位置中counter字符串的内容,并处理大小写。你知道吗

    我打赌你会同意我的看法

    if letter == 'a':
    

    更具可读性。因此,结合我前面的注释,您需要做的就是mirna = mirna.lower(),它将使所有字母都变为小写,并将比较的数量减少一半(这个“一半”预测并不完全正确,但您已经明白了)。

  3. 使用内置机制。

    createonewobble(mirna, counter+1 , wobblecount+1, compliment)
    

    此行将整个字符串作为一个参数和一个数字参数传递,该参数告诉函数从何处开始。这里的最佳实践是使用slices。这种机制只允许传递原始字符串的slice或窗口(如果愿意)。这样就不需要额外的数字参数。 如果我希望下一次对函数的调用遍历从counter+1位置开始的字符串,我可以执行以下操作:

    createonewobble(mirna[counter + 1:], wobblecount+1, compliment)
    

    这个语法的意思是[from:to],当其中一个被省略时,意味着从头到尾。More on slices

  4. Naming conventions是你应该读的东西。

总结

有很多,甚至是那些有经验的Python学习者每天都会学到一两样东西。 我真的推荐Code Review。这是提高Python写作技能的最佳地方。你知道吗

相关问题 更多 >

    热门问题