在for循环中循环并比较/变异类实例会导致意外的行为

2024-06-25 23:08:28 发布

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

我有一个类节点,它表示有向图上的一个节点。一个节点包含一个序列(一串字母,在本例中是DNA的4个碱基),以及由值k定义的前缀和后缀,其中前缀是序列的前k个字母,后缀是序列的最后k个字母。你知道吗

如果一个节点的后缀与另一个节点的前缀相同,则第一个节点应指向第二个节点,并且一个节点可以指向多个其他节点,但不能指向自身。你知道吗

我从一个文件中按顺序读取,从中列出一个节点列表,并尝试设置列表“nextNodes”,每个节点上的一个属性,其中包含它所指向的所有节点。你知道吗

在具有两个嵌套for-in循环的节点列表中循环,将每个节点与每个节点进行比较,将得到包含不应指向的节点的每个节点的“nextNodes”列表。此外,每个节点的列表都是相同的。你知道吗

我试着用itertools.组合方法来比较节点,认为问题在某种程度上与for-in循环和多次比较有关,但两种方法都会出现相同的行为。我很确定这个问题发生在for循环的执行中,但是我不知道它是什么。。。??你知道吗

下面是我的代码(Python2.7):

import itertools

class Node():

    def __init__(self, name, seq='', k=3, nextNodes=[]):
        self.name = name
        self.seq = seq
        self.k = k
        self.nextNodes = nextNodes
        if len(seq) > k:
            self.prefix = seq[:k]
            self.suffix = seq[-k:]
        else:
            self.prefix = 'PREFIX'
            self.suffix = 'SUFFIX'

    # ...

    def getSeq(self):
        return self.seq

    def setSeq(self, seq):
        self.seq = seq
        if len(seq) > self.k:
            self.prefix = seq[:self.k]
            self.suffix = seq[-self.k:]

    def getNextNodes(self):
        return self.nextNodes

    def setNextNode(self, node):
        self.nextNodes.append(node)

    def getPrefix(self):
        return self.prefix

    def getSuffix(self):
        return self.suffix

    def __str__(self):
        return self.name

nodes = []
curNode = None
with open('seqs.txt', 'r') as file:
    for line in file:
        if line[0] == '>':
            nodes.append(Node(line[1:].strip('\n')))
            curNode = nodes[-1]
        else:
            curNode.setSeq(curNode.getSeq() + line.strip('\n'))

# When either this for loop or the commented one runs, nextNodes is the
# same for every Node, and contains Nodes that should not be pointed to
for node in nodes:
    for otherNode in nodes:
        if node.getSeq() != otherNode.getSeq() \
        and node.getSuffix() == otherNode.getPrefix():
            node.setNextNode(otherNode)

"""
for node1, node2 in itertools.combinations(nodes, 2):
    if node1.getSeq() != node2.getSeq():
        if node1.getSuffix() == node2.getPrefix():
            node1.setNextNode(node2)
        if node2.getSuffix() == node1.getPrefix():
            node2.setNextNode(node1)
"""

for node in nodes:
    for nextNode in node.getNextNodes():
        print node, '->', nextNode

示例: 如果序列.txt'是:

>Node 1
AAACCCGGG
>Node 2
GGGTTTCCC
>Node 3
CCCGGGAAA

我们希望节点1指向节点2,节点2指向节点3,节点3指向节点1。但这就是结果:

Node 1 -> Node 2
Node 1 -> Node 1
Node 1 -> Node 3
Node 2 -> Node 2
Node 2 -> Node 1
Node 2 -> Node 3
Node 3 -> Node 2
Node 3 -> Node 1
Node 3 -> Node 3

Tags: inselfnodeforif节点defseq
1条回答
网友
1楼 · 发布于 2024-06-25 23:08:28

我认为,这里的问题是在Node的构造函数中将list用作nextNodes的默认值。列表是可变的,因此当您将默认值指定给self.nextNodes公司实际上,您正在为每个节点分配相同的列表,而不是新的列表。然后,当你在任何节点中附加到它时,它们都会得到,因为它们指向完全相同的列表。实际上,你的self.nextNodes公司实际上正在更改默认值。你知道吗

相关问题 更多 >