理解Python函数

3

我需要帮助理解一个函数,我想使用它,但我不确定它的某些部分是做什么的。我理解这个函数是从Fasta文件中读取字典创建函数。据我所知,这应该生成前缀和后缀字典,最终扩展contigs(重叠的DNA序列)。

代码:

def makeSuffixDict(reads, lenSuffix = 20, verbose = True):
    lenKeys = len(reads[0]) - lenSuffix
    dict = {}
    multipleKeys = []
    i = 1
    for read in reads:
        if read[0:lenKeys] in dict:
            multipleKeys.append(read[0:lenKeys])
        else:
            dict[read[0:lenKeys]] = read[lenKeys:]
        if verbose:
            print("\rChecking suffix", i, "of", len(reads), end = "", flush = True)
            i += 1
    for key in set(multipleKeys):
        del(dict[key])
    if verbose:
        print("\nCreated", len(dict), "suffixes with length", lenSuffix, \
            "from", len(reads), "Reads. (", len(reads) - len(dict), \
            "unambigous)")
    return(dict) 

额外信息:reads = readFasta("smallReads.fna", verbose = True)

这是调用该函数的方法:

if __name__ == "__main__":
    reads = readFasta("smallReads.fna", verbose = True)
    suffixDicts = makeSuffixDicts(reads, 10)

The smallReads.fna文件包含碱基(Dna)字符串:

"> 读取1

TTATGAATATTACGCAATGGACGTCCAAGGTACAGCGTATTTGTACGCTA

"> 读取2

AACTGCTATCTTTCTTGTCCACTCGAAAATCCATAACGTAGCCCATAACG

"> 读取3

TCAGTTATCCTATATACTGGATCCCGACTTTAATCGGCGTCGGAATTACT

这是我不理解的部分:
lenKeys = len(reads[0]) - lenSuffix

[0]的值是什么意思?据我所知,“len”返回列表中的元素数。为什么“reads”自动成为一个列表?编辑:似乎可以将Fasta文件声明为列表。有人能确认吗?

if read[0:lenKeys] in dict:

这是否意味着“从0到‘lenKeys’”?对该值仍感到困惑。 在另一个函数中有一条类似的语句:if read[-lenKeys:] in dict: “-”是什么作用?

def makeSuffixDict(reads, lenSuffix = 20, verbose = True):

这里我不理解参数是什么意思:怎么可能把reads作为一个参数?在该函数中,lenSuffix = 20除了从len(reads[0])中减去一个值以外,还有其他的含义吗? verbose是什么?我已经读到过"verbose-mode"可以忽略空格,但我从没见过它被用作一个参数并随后用作一个变量。


看起来很明显,这个 makeSuffixDict 函数期望 reads 实际上是一个列表(如果你不传递一个列表,它将无法工作)。你有关于这个函数的文档,指定它的要求吗? - Greg Hewgill
这里有很多问题,我会回答其中一些:方括号是切片符号,因此 read[:lenKeys] 的意思是“从 read 中取出索引号为 lenKeys 之前的所有内容”。同样地,read[-lenKeys] 只是一个索引,但使用了负数操作符。所以,“从 read 的末尾开始往前数 lenKeys 个对象”。 - a p
没有文档,Greg。我猜这是一个编程课程中的smallReads.fna文件提供的。我将编辑fna文件的内容,它可以被声明为列表。它包含碱基(DNA)的字符串。@a p:谢谢,这澄清了那一部分。 - grindbert
1个回答

3
你的问题语气让我感觉你正在混淆程序特性(如len、函数等)与原始程序员定义的事物(如reads的类型、verbose等)。请注意区分。
def some_function(these, are, arbitrary, parameters):
    pass

这个函数定义了一堆参数。它们除了隐式地给定的值外,实际上没有什么意义。例如,如果我执行以下操作:

def reverse_string(s):
    pass

s大概是一个字符串,对吗?在你的例子中,我们有:

def makeSuffixDict(reads, lenSuffix = 20, verbose = True):
    lenKeys = len(reads[0]) - lenSuffix
    ...

从这两行代码中,我们可以推断出以下一些信息:
  • 从函数名可以推测该函数可能会返回一个字典。
  • lenSuffix 是一个整数,verbose 是一个布尔值(根据它们的默认参数)。
  • reads 可以被索引(字符串?列表?元组?)。
  • reads 中的项有长度(字符串?列表?元组?)。

由于 Python 是动态类型语言,这是我们目前所能知道的全部关于函数的信息。其余的要么在文档中说明,要么通过调用来了解。

说到这里,让我按顺序回答你的问题:

  1. 什么是 [0] 的值?

some_object[0] 表示获取容器中的第一个项。例如,[1, 2, 3][0] == 1"Hello, World!"[0] == "H"。这被称为索引,受 __getitem__ 魔术方法控制。

  1. 据我所知,“len” 返回一个列表中元素的数量。

len 是一个内置函数,用于返回对象的长度。它受 __len__ 魔术方法控制。例如,len('abc') == 3len([1, 2, 3]) == 3。请注意,len(['abc']) == 1,因为它测量的是列表的长度,而不是字符串的长度。

  1. 为什么“reads”自动成为一个列表?

reads 是一个参数。它取决于调用该函数时传递给它的内容。看起来它期望一个列表,但这并不是硬性规则!

  1. (关于切片的各种问题)
切片是指对于some_container[start_idx : end_idx [ : step_size]]进行操作。它做的几乎就是你所期望的:"0123456"[0:3] == "012"。切片索引被认为是从零开始的,并且位于元素之间,因此[0:1][0]相同,但切片返回列表而不是单个对象(因此'abc'[0] == 'a',但'abc'[0:1] == ['a'])。如果省略起始或结束索引,则分别视为字符串的开头或结尾。这里不讨论步长。
负索引从后面计数,因此'0123456'[-3:] == '456'。请注意,[-0]不是最后一个值,[-1]才是。这与[0]`表示第一个值不同。
5. 读取如何成为参数?
因为函数被定义为makeSuffixDict(reads, ...)。这就是参数的定义。
6. 在该函数的上下文中,lenSuffix = 20是什么意思?
看起来它是期望后缀的长度!
7. verbose是什么? verbose本身没有意义。它只是另一个参数。看起来作者包括了verbose标志,以便您在函数运行时获得输出。请注意,所有if verbose块似乎什么都不做,只是向用户提供反馈。

从您的编辑中注意到:reads = readFasta("smallReads.fna", verbose = True) 中的 reads 在模块作用域中,而 makeSuffixDict 中的 reads 在函数作用域中。它们是不同的!虽然我猜测 makeSuffixDict 是使用相同的 reads 变量调用的。 - Adam Smith
谢谢!这解释了很多问题。我是 Python 的新手,所以确实会混淆很多东西。我已经编辑了如何调用函数的问题。 - grindbert
据我所了解,这应该生成前缀和后缀字典,最终用于扩展contigs(重叠的DNA序列)。我刚刚添加了这个内容到初始帖子中。 - grindbert
@grindbert 是的,我对这个主题一无所知。在我看来,reads 是一个字符串列表,每个字符串应该具有相同的长度,因此 lenKeys 只计算一次,所以 read[:lenKeys] 是后缀之前的所有内容,而 read[lenSuffix:] 是后缀。 - Adam Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接