我有一本包含列表清单的字典:
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名称成对地查看数据(我在另一个文件中有一个对列表,但对于这个问题,我们只说Locus_1
和Locus_2
是一个对)。
因此,对于Locus_1:Locus_2
对,我需要匹配每个locus-list(SafrXX)中位置0的名称。对于那些相等的(So Locus_1:Safr02-Locus_2:Safr02
),我需要比较位置1处的字母 - 所以对于这个例子,字母将是:R:Y
。
为了使它变得更加棘手,我需要对位置2的值的所有组合执行此操作。
所以我在上面要比较的字母是:
R:Y
R:T
K:Y
K:T
现在,我并不是要求您编写一段代码,实际上可以执行此操作,但是,分离和处理此任务的最合理的方法是什么?有没有我可以先做的事情,所以我不必在复杂的多个嵌套循环中做所有事情?
答案 0 :(得分:0)
我认为这里描述的问题并不好。或者更好的是,您提供的数据的依赖关系将解释您需要的输出。
我用你的代码玩了一下,首先我认为通过像这样使用zip function的python会很简单:
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)
这给了我以下输出,它不会帮助你,因为第一个列未排序且不匹配:
['>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)
所以你看,如果你在一个嵌套循环中完成它,你将很容易实现你的目标 - 至少靠近它一步。但是,您似乎正在寻找正确处理数据所需的逻辑,而不会告诉我们数据背后的逻辑。
使用代码你已经可以匹配列表并将field1中的字母与field2的所有组合进行比较,但是field3的数量应该如何影响你的输出我不清楚。
无论如何,我希望这至少有一点帮助。
答案 1 :(得分: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)