【问题标题】:python: iterate through dynamic listpython:遍历动态列表
【发布时间】:2016-05-29 04:18:10
【问题描述】:

从一组序列(字符串)中,我想生成一个子集字典,其中每个序列代表一个键,并且值应该是最多在“匹配”(例如 1)位置匹配的所有序列,既有原始序列(键),也有当时子集中的所有值条目。

例如,考虑到由“A”、“C”、“G”和“T”组成的所有长度为 3 的序列,其中一个键值对应该是(或可能是,因为有更多可能的方式选择这样的一组)。

这是我想出的定义:

def pick(seq,superset):
    subset = [seq]
    for seq in subset:
        count = 0
        for item in superset:
            if len([i for i, j in zip(list(seq),list(item)) if i==j])==match:
                count += 1
                if len(subset)==count:
                    subset += [''.join(item)]
    return subset

我得到了什么:

{'AAA': ['AAA', 'ACC', 'ACG', 'ACT', 'AGC', 'AGG', 'AGT', 'ATC', 'ATG', 'ATT', 'CAC', 'CAG',
'CAT', 'CCA', 'CGA', 'CTA', 'GAC', 'GAG', 'GAT', 'GCA', 'GGA', 'GTA', 'TAC', 'TAG', 'TAT',
'TCA', 'TGA', 'TTA']}

我想要什么:

{'AAA': ['CCC','GGG','TTT','ACG','CGT','GTA','TAC']}

我遇到的问题是,我现在只生成一个子集,其中值与键的匹配不超过一个位置,但值序列确实有多个位置与子集中的其他值特定匹配。有没有人有这个问题的(n 优雅的)解决方案?

【问题讨论】:

  • 我不确定你到底在问什么,但总的来说,在迭代列表的同时从列表中删除项目是不安全的。这会混淆迭代器变量,并可能导致某些项目看似被跳过。考虑一种不需要for item in copy: copy.remove(item) 的不同方法。
  • 谢谢凯文,我现在已经改变了。这并不能解决我遇到的问题,我把它放在那里是因为我认为这样可以节省我的时间,而不必遍历在第一个循环之后我已经可以丢弃的项目。

标签: python list dynamic iterable


【解决方案1】:

我将您的问题解释为“我想获取 superset 中介于 0 和 match 之间的所有项目的列表与 seq 匹配的字符。但现在我的函数返回所有项目的列表完全 match 匹配字符的项目。此外,返回列表的第一个元素等于 seq,这是我不想要的。"

出现第一个问题是因为您在比较匹配时使用了“==”,而不是“subset 初始化为包含seq,即使您不需要这样做。也没有必要有两个for 循环。此外,在向列表中添加项目时,请考虑使用 append 而不是 +=,因为它几乎总是更有效。

def pick(seq,superset,match):
    subset = []
    for item in superset:
        if len([i for i, j in zip(list(seq),list(item)) if i==j])<=match:
            subset.append(''.join(item))
    return subset

superset = [
    'GGG', 'GGC', 'GGA', 'GGT', 'GCG', 'GCC', 'GCA', 'GCT', 'GAG', 'GAC', 'GAA', 'GAT', 'GTG', 'GTC', 'GTA', 'GTT', 
    'CGG', 'CGC', 'CGA', 'CGT', 'CCG', 'CCC', 'CCA', 'CCT', 'CAG', 'CAC', 'CAA', 'CAT', 'CTG', 'CTC', 'CTA', 'CTT', 
    'AGG', 'AGC', 'AGA', 'AGT', 'ACG', 'ACC', 'ACA', 'ACT', 'AAG', 'AAC', 'AAA', 'AAT', 'ATG', 'ATC', 'ATA', 'ATT', 
    'TGG', 'TGC', 'TGA', 'TGT', 'TCG', 'TCC', 'TCA', 'TCT', 'TAG', 'TAC', 'TAA', 'TAT', 'TTG', 'TTC', 'TTA', 'TTT'
]

seq = "AAA"

print pick(seq, superset, 1)

结果(为清楚起见,我添加了换行符):

['GGG', 'GGC', 'GGA', 'GGT', 'GCG', 'GCC', 'GCA', 'GCT', 'GAG', 'GAC', 'GAT', 'GTG', 'GTC', 'GTA', 'GTT', 
'CGG', 'CGC', 'CGA', 'CGT', 'CCG', 'CCC', 'CCA', 'CCT', 'CAG', 'CAC', 'CAT', 'CTG', 'CTC', 'CTA', 'CTT', 
'AGG', 'AGC', 'AGT', 'ACG', 'ACC', 'ACT', 'ATG', 'ATC', 'ATT', 
'TGG', 'TGC', 'TGA', 'TGT', 'TCG', 'TCC', 'TCA', 'TCT', 'TAG', 'TAC', 'TAT', 'TTG', 'TTC', 'TTA', 'TTT']

编辑:如果每个潜在项目还必须满足与子集的每个其他现有元素的匹配条件,您可以使用all 和列表推导来检查这一点。请注意,函数返回的值取决于superset 的顺序,因为有多个不同的局部最大值可以满足条件。

def similarity(a,b):
    return sum(1 for p,q in zip(a,b) if p==q)

def pick(seq, superset, match):
    subset = []
    for item in superset:
        if similarity(item, seq) <= match and all(similarity(item, x) <= match for x in subset):
            subset.append(item)
    return subset

superset = [
    'GGG', 'GGC', 'GGA', 'GGT', 'GCG', 'GCC', 'GCA', 'GCT', 'GAG', 'GAC', 'GAA', 'GAT', 'GTG', 'GTC', 'GTA', 'GTT', 
    'CGG', 'CGC', 'CGA', 'CGT', 'CCG', 'CCC', 'CCA', 'CCT', 'CAG', 'CAC', 'CAA', 'CAT', 'CTG', 'CTC', 'CTA', 'CTT', 
    'AGG', 'AGC', 'AGA', 'AGT', 'ACG', 'ACC', 'ACA', 'ACT', 'AAG', 'AAC', 'AAA', 'AAT', 'ATG', 'ATC', 'ATA', 'ATT', 
    'TGG', 'TGC', 'TGA', 'TGT', 'TCG', 'TCC', 'TCA', 'TCT', 'TAG', 'TAC', 'TAA', 'TAT', 'TTG', 'TTC', 'TTA', 'TTT'
]

seq = "AAA"

print pick(seq, superset, 1)

结果:

['GGG', 'GCC', 'GAT', 'GTA', 'CGC', 'CCG', 'CTT', 'AGT', 'ATG', 'TGA', 'TCT', 'TAG', 'TTC']

【讨论】:

  • 它仍然返回一个集合,其中序列与该子集中的其他序列在多个位置匹配。我已经用我得到的输出和我需要的输出更新了我的问题。
  • 太棒了,这正是我想要的。我不能为你+1,因为我不是很有名气,所以我希望其他人会;)
  • 没关系 :-) 如果对您有用,请随时 accept my answer
  • 好的,完成。不过有趣的是,您会陷入局部最优,这意味着某些键的序列列表比其他键长。可能也有办法解决这个问题,但我不一定需要这个。如果您愿意,欢迎您尝试尝试,确保所有值都包含 15 个元素,我会觉得这很有趣,但我认为这将非常困难。我能想到的最简单的解决方案是为每个键生成多个子集并选择最长的一个。
猜你喜欢
  • 2021-12-24
  • 2020-03-30
  • 1970-01-01
  • 2013-02-18
  • 1970-01-01
  • 2018-03-08
  • 2015-10-07
  • 2013-07-13
相关资源
最近更新 更多