【问题标题】:python script not joining strings as expectedpython脚本未按预期加入字符串
【发布时间】:2020-03-27 15:10:39
【问题描述】:

我有一个序列列表列表,以及一个对应的名称列表列表。

testSequences = [
    ['aaaa', 'cccc'],
    ['tt', 'gg'],
    ['AAAAAAA', 'CCCCCC', 'TTTTTT', 'GGGGGG']]
testNames = [
    ['>xx_oneFish |xzx', '>xx_twoFish |zzx'],
    ['>xx_redFish |zxx', '>xx_blueFish |zxx'],
    ['>xx_oneFish |xzx', '>xx_twoFish |xzx', '>xz_redFish |xxx', '>zx_blueFish |xzz']]

我还列出了姓名的所有识别部分:

taxonNames = ['oneFish', 'twoFish', 'redFish', 'blueFish']

我正在尝试生成一个新列表,其中列表中的每个项目都将对应于“名称的标识部分”之一,并且该字符串将由该名称的所有序列组成。

如果名称和序列未出现在列表中的一个列表中(即testNames 的第一个列表中没有redFishblueFish)我想添加一串相同长度的连字符作为该列表中的序列。这会给我这个输出:

['aaaa--AAAAAA', 'cccc--CCCCCC', '----ttTTTTTT', '----ggGGGG']

我有这段代码可以做到这一点。

complete = [''] * len(taxonNames)

for i in range(len(testSequences)):
    for j in range(len(taxonNames)):
        sequenceLength = len(testSequences[i][0])
        for k in range(len(testSequences[i])):
            if taxonNames[j] in testNames[i][k]:
                complete[j].join(testSequences[i][k]) 
            if taxonNames[j] not in testNames[i][k]:
                hyphenString = "-" * sequenceLength
                complete[j].join(hyphenString)

print complete

“完成”应该给出我上面解释的最终输出,但它看起来像这样:

['', '', '', '']

如何修复我的代码以给出正确答案?

【问题讨论】:

  • 表达式complete[j].join(testSequences[i][k]) 返回一个新字符串。您对该字符串不执行任何操作,它会立即被丢弃。 Python 字符串是不可变的。这不会影响complete[j] 内的str 对象
  • @juanpa.arrivillaga 我怎样才能修改我的代码,让它给我正确的答案?
  • 你需要修改列表,所以complete[j] = complete[j].join(testSequences[i][k])
  • @juanpa.arrivillaga 从第 9 行及以下删除 if not 语句,并将第 8 行从 complete[j].join(testSequences[i][k]) 更改为 complete[j] = complete[j].join(testSequences[i][k]) 给我这个:['AaaaaAaaaaAaaaaAaaaaAaaaaAaaaaA', 'CccccCccccCccccCccccCccccC', 'TttTttTttTttTttT', 'GggGggGggGggGggG']
  • 为什么'aaaa--AAAAAA' 有两个连字符,'----ttTTTTTT' 有四个连字符?

标签: python string list loops


【解决方案1】:

代码的主要问题是很难理解,因为你没有真正利用使 Python 如此强大的语言元素。

以下是解决您问题的有效方法:

test_sequences = [
    ['aaaa', 'cccc'],
    ['tt', 'gg'],
    ['AAAAAAA', 'CCCCCC', 'TTTTTT', 'GGGGGG']]
test_names = [
    ['>xx_oneFish |xzx', '>xx_twoFish |zzx'],
    ['>xx_redFish |zxx', '>xx_blueFish |zxx'],
    ['>xx_oneFish |xzx', '>xx_twoFish |xzx', '>xz_redFish |xxx', '>zx_blueFish |xzz']]

taxon_names = ['oneFish', 'twoFish', 'redFish', 'blueFish']


def get_seqs(taxon_name, sequences_list, names_list):
    for seqs, names in zip(sequences_list, names_list):
        found_seq = None
        for seq, name in zip(seqs, names):
            if taxon_name in name:
                found_seq = seq
                break
        yield found_seq if found_seq else '-' * len(seqs[0])


result = [''.join(get_seqs(taxon_name, test_sequences, test_names)) 
          for taxon_name in taxon_names]

print(result)

生成器get_seqstest_sequencestest_names 中的列表配对,并且对于每一对,尝试找到匹配的名称(name)的序列(seq)并产生它,或产生该序列列表的正确数量的连字符的字符串。

生成器(产生多个值的函数)的代码完全符合上述说明。

结果就是,对于每个taxon_name,按顺序获取所有匹配的结果序列并将它们连接到一个字符串中,这就是result = ... 行。

你可以让它与列表索引循环和字符串连接一起工作,但这不是 PHP 问题,现在是吗? :)

注意:为简洁起见,您可以只访问全局 test_sequencestest_names 而不是将它们作为参数传递,但我认为如果您要实际使用此代码,那会再次困扰您。另外,我认为在整个示例中更改名称和序列的顺序在语义上是有意义的,但我并没有避免进一步偏离您的示例。

【讨论】:

  • 谢谢,我认为问题的部分原因是我对 python 有基本的了解,所以除了列表索引循环和字符串连接之外还没有涵盖太多
  • 是的,没关系,我尝试先修复您的代码,但需要进行很多更改,我想我最好只分享一个很好的示例,说明如何在 Python 中执行此操作
【解决方案2】:

这是一个可以满足您需求的解决方案。它不是从你这篇文章中的数据结构开始的,而是从你的previous post(你用来构建这篇文章的数据结构)中的三个示例文件开始的。

我唯一想不通的是文件中缺少的序列要使用多少连字符。

differentNames = ['oneFish', 'twoFish', 'redFish', 'blueFish']
files = ['f1.txt', 'f2.txt', 'f3.txt']

data = [[] for _ in range(len(differentNames))]
final = []

for file in files:
    d = dict()
    with open(file, 'r') as fin:
        for line in fin:
            line = line.rstrip()
            if line.startswith('>'): # for ex., >xx_oneFish |xxx
                underscore = line.index('_')
                space = line.index(' ')
                key = line[underscore+1:space]
            else:
                d[key] = line

    for i, key in enumerate(differentNames):
        data[i].append(d.get(key, '-' * 4))

for array in data:
    final.append(''.join(array))

print(final)

打印:

['AAAAAAAaaaa----', 'CCCCCCcccc----', 'TTTTTT----tt', 'GGGGGG----gg']

【讨论】:

  • 感谢您的解决方案。添加的连字符数是使所有序列长度相同(在本例中为 12 个字符)所需的数量。在testSequences 的第一个列表中,存在的序列长度为 4 个字母。 redFishblueFish 没有字母,所以我添加了 4 个连字符以保持下一个要添加的序列列表的对齐。在testSequences 的下一个列表中,存在的序列长度为 2 个字母,oneFishtwoFish 没有字母,因此它们有两个连字符。希望这可以澄清。
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-20
  • 2012-10-31
相关资源
最近更新 更多