2015-04-24 109 views
4

我有一本字典方含列表的列表:匹配索引蟒蛇

d = [('Locus_1', 
    [['>Safr02', 'R', '104'], 
    ['>Safr03', 'G', '104'], 
    ['>Safr04', 'A', '104'], 
    ['>Safr10', 'A', '104'], 
    ['>Safr02', 'K', '110'], 
    ['>Safr03', 'T', '110'], 
    ['>Safr04', 'T', '110'], 
    ['>Safr10', 'T', '110']]), 
('Locus_2', 
    [['>Safr01', 'C', '15'], 
    ['>Safr02', 'Y', '15'], 
    ['>Safr04', 'Y', '15'], 
    ['>Safr07', 'Y', '15'], 
    ['>Safr01', 'Y', '78'], 
    ['>Safr02', 'T', '78'], 
    ['>Safr04', 'T', '78'], 
    ['>Safr07', 'T', '78']])] 

本词典是用下面的代码创建:

snp_file = open(sys.argv[2], 'r') 
snps = csv.reader(snp_file, delimiter=',') 

d = OrderedDict() 

for row in snps: 
    key = row[0] 
    d.setdefault(key,[]) 
    d[key].append(row[1:]) 

的数据可以在这里找到:https://www.dropbox.com/sh/3j4i04s2rg6b63h/AADkWG3OcsutTiSsyTl8L2Vda?dl=0

我有一个复杂的任务在这个数据上做的一点,我想分成几个步骤,但我不知道如何做到这一点:

我需要关于Locus_X-name(我在另一个文件中有一个对列表,但是对于这个问题,我们只需说Locus_1Locus_2是一对)数据配对。

所以对于Locus_1:Locus_2我需要匹配每个轨迹列表(SafrXX)中位置0处的名称。对于那些相同的(所以Locus_1:Safr02-Locus_2:Safr02),我需要比较位置1的字母 - 因此在这个例子中,字母是:R:Y

为了使其更加棘手,我需要在位置值的所有组合做2.

所以我需要在上面进行比较的字母,将是:

R:Y 
R:T 
K:Y 
K:T 

现在,我并不是要求你写一段代码,它实际上可以做到这一点,但是,分离和接近这个任务最合乎逻辑的方式是什么?有什么我可以先做的,所以我不必在复杂的多重嵌套循环中做所有事情?

+1

你可以发布一条线的你的输出应该是什么样子?看看你的数据,除了第一个字段外,没有明确的依赖关系。 –

回答

0

我觉得这里的问题不好描述。或者更好的是,你提供的数据的依赖关系可以解释你需要的输出。

我打了一下周围与您的代码,开始我还以为这将是简单的通过只是使用python的zip function这样的:

import csv 
from collections import OrderedDict 

snp_file = open('data.txt', 'r') 
snps = csv.reader(snp_file, delimiter=',') 
d = OrderedDict() 
for row in snps: 
    key = row[0] 
    d.setdefault(key,[]) 
    d[key].append(row[1:]) 

for left,right in zip(d['Locus_1'],d['Locus_2']): 
    print(left,right) 

这给了我下面的输出,这将不帮助你要么,因为第一colums是无序和不匹配:

['>Safr02', 'R', '104'] ['>Safr01', 'C', '15'] 
['>Safr03', 'G', '104'] ['>Safr02', 'Y', '15'] 
['>Safr04', 'A', '104'] ['>Safr04', 'Y', '15'] 
['>Safr10', 'A', '104'] ['>Safr07', 'Y', '15'] 
['>Safr02', 'K', '110'] ['>Safr01', 'Y', '78'] 
['>Safr03', 'T', '110'] ['>Safr02', 'Y', '78'] 
['>Safr04', 'T', '110'] ['>Safr04', 'T', '78'] 
['>Safr10', 'T', '110'] ['>Safr07', 'T', '78'] 

添加一个排序,以这样的剧本没有再帮助,因为列表长度相等,但第一个键不匹配您的数据:

loc1 = sorted(d['Locus_1'], key=lambda lst: lst[0]): 
loc2 = sorted(d['Locus_2'], key=lambda lst: lst[0]): 

for left,right in zip(loc1,loc2): 
    print(left,right) 

这使下面的屏幕:

['>Safr02', 'R', '104'] ['>Safr01', 'C', '15'] 
['>Safr02', 'K', '110'] ['>Safr01', 'Y', '78'] 
['>Safr03', 'G', '104'] ['>Safr02', 'Y', '15'] 
['>Safr03', 'T', '110'] ['>Safr02', 'Y', '78'] 
['>Safr04', 'A', '104'] ['>Safr04', 'Y', '15'] 
['>Safr04', 'T', '110'] ['>Safr04', 'T', '78'] 
['>Safr10', 'A', '104'] ['>Safr07', 'Y', '15'] 
['>Safr10', 'T', '110'] ['>Safr07', 'T', '78'] 

所以我切换到嵌套循环,看看我是否能掌握多一点的数据是如何处理的:

for l1 in loc1: 
    for l2 in loc2: 
     if l1[0] == l2[0]: 
      print('{}-{}({}):{}({})'.format(l1[0],l1[1],l1[2],l2[1],l2[2])) 

但是,这也不能给我一个线索,但看到你自己(输出是简短的原因,我仍然没有把握要点):

>Safr02-R(104):Y(15) 
>Safr02-R(104):Y(78) 
>Safr02-K(110):Y(15) 
>Safr02-K(110):Y(78) 
>Safr04-A(104):Y(15) 
>Safr04-A(104):T(78) 
>Safr04-T(110):Y(15) 
>Safr04-T(110):T(78) 

所以你看,如果你用嵌套循环的方式来做,你的目标就会相当容易 - 至少离它更近一步。但是您似乎正在寻找正确处理数据所需的逻辑,而没有告诉我们数据背后的逻辑。

通过代码,您可以匹配列表并通过field2的匹配比较字段1中的所有组合,但field3的数量应该如何影响您的输出对我而言并不清楚。

无论如何,我希望这至少有助于一点。

0

这是我的解决方案。将pair变量替换为要检查的任何双轨迹对。我将行的索引添加到元组中,因此排序很重要。

import csv 

snp_file = open('input.txt', 'r') 
snps = csv.reader(snp_file, delimiter=',') 
pair=(1,2)#the choosen pair 

dic={} 
i=0 
for row in snps: 
    if row==[]: break 
    locus=int(row[0][len('locus_'):]) 
    safr=int(row[1][len('>safr'):]) 
    letter=row[2] 
    number=row[3] 
    index=i 
    if (locus, safr) in dic: 
     dic[locus, safr].append((letter, number, index)) 
    else: 
     dic[locus, safr]=[(letter, number, index)] 
    i+=1 

for key in dic: 
    if key[0]==pair[0] and (pair[1], key[1]) in dic: 
     for e in dic[key]: 
      for f in dic[pair[1], key[1]]: 
       print e, ' ', f 

这给出了以下的输出:

('R', '104', 0) ('Y', '15', 9) 
('R', '104', 0) ('T', '78', 13) 
('K', '110', 4) ('Y', '15', 9) 
('K', '110', 4) ('T', '78', 13) 
('A', '104', 2) ('Y', '15', 10) 
('A', '104', 2) ('T', '78', 14) 
('T', '110', 6) ('Y', '15', 10) 
('T', '110', 6) ('T', '78', 14)