2015-04-24 106 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)