我一直在使用Python字典用COG / NOG标识符替换md5值。这就是我到目前为止所做的......
#!/usr/bin/python
import sys
fil = sys.argv[1]
# load md5 -> COG into dictionary
with open(fil) as fin:
rows = ( line.strip().split('\t') for line in fin )
d = { row[0]:row[1] for row in rows }
# open blast output, replace md5 with COG by looking up md5 in the dictionary
blasted = open(sys.argv[2])
for line in blasted:
linearr = line.split()
if linearr[2] > '90.00':
line.split()
needed = linearr[0:2]
md5 = linearr[1]
ret = []
for md5 in needed:
ret.append(d.get(md5,md5))
"".join(ret)
print ret
这使我得到了这个输出,各种大小和内容的列表......
['fig|357276.26.peg.4486']
['fig|357276.26.peg.4486', 'f3e68ef307f962ba6b836a94ff0e2216']
['fig|357276.26.peg.4486']
['fig|357276.26.peg.4486', 'COG0860']
['fig|357276.26.peg.4486']
['fig|357276.26.peg.4486', '05e94199eef6fbaf225618f9deaf847c']
因此需要抛出单个项目列表以及保留md5值的列表。我需要的是只选择具有COG / NOG第二个元素的列表,如上面的第4个列表。
我无法选择列表的第二项来过滤这些结果,因为并非所有列表都有第二项。任何人都可以为此建议一种方法吗?
更新: 我只能用一个项目删除列表。现在我的列表看起来像这样......
['fig|357276.26.peg.4485', 'NOG73961']
['fig|357276.26.peg.4485', '19c060b530e8fa9598de068387bc3225']
['fig|357276.26.peg.4486', '8daa25fe83eb1a204c51861cb77945f5']
['fig|357276.26.peg.4486', '5c253078a0a6c51eca320dfd92991a70']
['fig|357276.26.peg.4486', '8707bd7fa7489ff69233ce735c1c6cbf']
['fig|357276.26.peg.4486', 'f3e68ef307f962ba6b836a94ff0e2216']
['fig|357276.26.peg.4486', 'COG0860']
['fig|357276.26.peg.4486', '05e94199eef6fbaf225618f9deaf847c']
现在我只需要选择包含以NOG或COG开头的第二项的列表......任何建议?
答案 0 :(得分:1)
假设您有一个列表,例如values = [ [1], [1,2], [3,4] ]
首先,使用filter
功能删除所有项目:
values1 = filter(lambda x: len(x) > 1, values)
现在您需要根据COG / NOG进行过滤。由于现在只有2个元素的列表,我们可以直接选择第二个元素:
filter(lambda x: "NOG" in x[1] of "COG" in x[1], values1)
为了减少整个事情,我们可以合并两者:
def check_cog_nog(x):
if len(x) > 1:
y = x[1].lower()
if "nog" in y or "cog" in y:
return True
return False
filter(check_cog_nog, values)
答案 1 :(得分:0)
在尝试访问第二个元素之前,只需使用len()检查列表是否足够长。
[编辑:就像上面的第一条评论一样,在我开始这个答案后发布了。 (我没有足够的声誉来评论自己。)]
[编辑2:这里有一些关于你的代码的注释。除非您确定数据来源,否则您可能需要考虑进行一些检查,以确保每一行都符合您的需要。]
blasted = open(sys.argv[2])
for line in blasted:
linearr = line.split()
if linearr[2] > '90.00': # <-- this will blow up if not enough elements
line.split() # <--- this doesn't do anything
needed = linearr[0:2] # <- this could get 0-3 elements
md5 = linearr[1] # <-- This will blow up if not enough elements
ret = []
for md5 in needed:
ret.append(d.get(md5,md5))
"".join(ret)
print ret
答案 2 :(得分:0)
如果您的列表存储在variable
ret
中,那么您可以使用此列表理解来实现您的需求:
new_ret = [i for i in ret if len(i) > 1 and (i[1].startswith('COG') or i[1].startswith('NOG'))]
print (new_ret)
输出:
[['fig|357276.26.peg.4486', 'COG0860']]
如果ret
包含i[1]
以NOD
开头的元素,new_ret
也会包含这些元素。