是否有不在字典中插入键的特殊值

Is there a special value that doesn't insert a key in a dictionary

有没有一种方法可以将特殊键分配给实际上什么都不做的字典?

我想做这样的事情:

mydict = {}
key, value = 'foo', 'bar'
mydict[key] = value   % now my dict has {'foo': 'bar'}

现在我想要一些 "special" 键值,这样当我 运行:

mydict[key] = value

它实际上没有做任何事情,所以 mydict 仍然是 {'foo': 'bar'}(没有添加额外的键或值)

我尝试使用:

d[None] = None   # It actually adds {None: None} to the dict
d[] = []         # Invalid syntax

为什么我需要这个:

嗯,基本上是处理一个初步的案例。

我有一个实际上是 FASTA 格式的文件:

>id_3362
TGTCAGTGTTCCCCGTGGCCCTGCGGTTGGAATTGCAGCGGGTCGCTTTAGTTCTGGCAT
ATATTTTGACGGTGCCGGCCGGCGATACTGACGTGTGAGGACTTGAATTTGTACCAGCGC
AACACTTCCAAAGCCTGGACTAGGTTGT
>id_4743
CGGGGGATCTAATGTGGCTGCCACGGGTTGAAAAATGG
>id_5443
ATATTTTGACGGTGCCGGCCGGCGATACTGACGTGTGAGGACTTGAATTTGTACCAGCGC
AACACTTCCAAAGCCTGGACTAGGTTGT

我的方法是逐行读取,将各行连接成一个序列,直到找到下一个键(以 > 开头的行)。 然后我将键 (id) 与关联值 (序列) 保存在字典中,更新键并开始累积下一个序列。

当然我可以有一个专门的代码(重复)来处理第一种情况(我认为这不是一个干净的方法)或者我可以在循环中有一个 if 来读取每一行(这每次都会执行)

所以最干净的方法是每次找到一个 id 时,将前一个 id 和累积的 seq 保存到字典中,但是为了处理第一行,我需要一些特殊的键值。

这是我的代码:

def read_fasta(filename):
    mydict = {}
    id = None      # this has to be the special character I'm looking for
    seq = ''

    with open(filename) as f:            
        for line in f:
            if line[0] == '>':
                mydict[id] = seq             # save current id and seq
                id = line[1:].rstrip('\n')   # update id
                seq = ''                     # clean seq
            else:
                seq += line.rstrip('\n')     # accumulate seq

如您所见,在这段代码中,第一行会将值 {None:''} 插入到字典中。

我当然可以在最后删除这个键,但我想知道我是否可以有一个在执行时不插入任何东西的初始值。

有什么建议吗?

你当然可以这样做:

id = None

然后:

if id is not None: mydict[id] = seq

如果你想在没有 if 测试的情况下避免插入,你也可以在开始时使用 non-hashable 值。

id = []

然后赶上"unhashable exception"。那会工作,虽然丑陋,但没有额外的开销,因为异常只被触发一次。

   try:
      mydict[id] = seq
   except TypeError:
      pass

旁白:如果您关心速度,则不要使用字符串连接

seq += line.rstrip('\n')

表现非常糟糕。相反:

  • seq 定义为 list: seq = []
  • 将行附加到 seqseq.append(line.rstrip('\n'))
  • 最后创建最终字符串:seq = "".join(seq)