列表列表中的匹配索引 - 字典 - python

Posted

技术标签:

【中文标题】列表列表中的匹配索引 - 字典 - python【英文标题】:Matching indexes in list of lists - dictionary - python 【发布时间】:2015-07-03 01:21:09 【问题描述】:

我有一本包含列表列表的字典:

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_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】:

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

我玩了一下你的代码,首先我认为这会很简单,只需使用 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)

这给了我以下输出,这对您也无济于事,因为第一列未排序且不匹配:

['>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 的匹配来比较 field1 中的字母以获得所有组合,但我不清楚 field3 的数字应该如何影响您的输出。

无论如何,我希望这至少会有所帮助。

【讨论】:

【参考方案2】:

这是我的解决方案。将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)

【讨论】:

以上是关于列表列表中的匹配索引 - 字典 - python的主要内容,如果未能解决你的问题,请参考以下文章

以最快的方式从数据框 Python 中的索引创建一个新的字典列表

python字典和列表区别都有哪些

python 列表,字典,元组

python学习笔记第四节

比较python中的两个列表并返回匹配值的索引

python 列表元组字典字典的区别