Python 如何找到两个列表之间的匹配项并根据匹配项写入输出?
我不确定我是否把问题的标题放得恰当。但是,我试着在下面解释这个问题。如果你能思考这个问题,请建议合适的标题 假设我有两种类型的列表数据:Python 如何找到两个列表之间的匹配项并根据匹配项写入输出?,python,python-2.7,for-loop,if-statement,list-comprehension,Python,Python 2.7,For Loop,If Statement,List Comprehension,我不确定我是否把问题的标题放得恰当。但是,我试着在下面解释这个问题。如果你能思考这个问题,请建议合适的标题 假设我有两种类型的列表数据: list_headers = ['gene_id', 'gene_name', 'trans_id'] # these are the features to be mined from each line of `attri_values` attri_values = ['gene_id "scaffold_200001.1"', 'gene_ve
list_headers = ['gene_id', 'gene_name', 'trans_id']
# these are the features to be mined from each line of `attri_values`
attri_values =
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"']
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'trans_id "scaffold_200001.1"', 'transcript_version "1"', 'exon_number "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200001.1.exon1"', 'exon_version "1"']
['gene_id "scaffold_200002.1"', 'gene_version "1"', 'trans_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "3"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon3"', 'exon_version "1"']
gene_id gene_name trans_id
scaffold_200001.1 NA NA
scaffold_200001.1 NA scaffold_200001.1
scaffold_200002.1 NA scaffold_200002.1
gene_id gene_name trans_id
scaffold_200001.1
scaffold_200001.1 scaffold_200001.1
scaffold_200002.1 scaffold_200002.1
我正试图根据标题中的列表和属性值中的属性的匹配情况创建一个表
output = open('gtf_table', 'w')
output.write('\t'.join(list_headers) + '\n') # this will first write the header
# then I want to read each line
for values in attri_values:
for list in list_headers:
if values.startswith(list):
attr_id = ''.join([x for x in attri_values if list in x])
attr_id = attr_id.replace('"', '').split(' ')[1]
output.write('\t' + '\t'.join([attr_id]))
elif not values.startswith(list):
attr_id = 'NA'
output.write('\t' + '\t'.join([attr_id]))
output.write('\n')
问题:是当在属性值的值中找到列表标题列表中的匹配字符串时,所有字符串都工作正常,但当没有匹配时,会有大量重复的“NA”
最终预期结果:
list_headers = ['gene_id', 'gene_name', 'trans_id']
# these are the features to be mined from each line of `attri_values`
attri_values =
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"']
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'trans_id "scaffold_200001.1"', 'transcript_version "1"', 'exon_number "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200001.1.exon1"', 'exon_version "1"']
['gene_id "scaffold_200002.1"', 'gene_version "1"', 'trans_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "3"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon3"', 'exon_version "1"']
gene_id gene_name trans_id
scaffold_200001.1 NA NA
scaffold_200001.1 NA scaffold_200001.1
scaffold_200002.1 NA scaffold_200002.1
gene_id gene_name trans_id
scaffold_200001.1
scaffold_200001.1 scaffold_200001.1
scaffold_200002.1 scaffold_200002.1
后期编辑:
这就是我如何编写elif
的问题(因为对于每一个不匹配项,它都会写入'NA')。我尝试以不同的方式移动NA
的条件,但没有成功如果我删除elif
它会以(NA
丢失)的形式获得输出:
list_headers = ['gene_id', 'gene_name', 'trans_id']
# these are the features to be mined from each line of `attri_values`
attri_values =
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"']
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'trans_id "scaffold_200001.1"', 'transcript_version "1"', 'exon_number "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200001.1.exon1"', 'exon_version "1"']
['gene_id "scaffold_200002.1"', 'gene_version "1"', 'trans_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "3"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon3"', 'exon_version "1"']
gene_id gene_name trans_id
scaffold_200001.1 NA NA
scaffold_200001.1 NA scaffold_200001.1
scaffold_200002.1 NA scaffold_200002.1
gene_id gene_name trans_id
scaffold_200001.1
scaffold_200001.1 scaffold_200001.1
scaffold_200002.1 scaffold_200002.1
python为字符串提供了一个find
方法,您可以使用该方法为每个属性值迭代每个列表头。尝试使用此功能:
def Get_Match(search_space,search_string):
start_character = search_space.find(search_string)
if start_character == -1:
return "N/A"
else:
return search_space[(start_character + len(search_string)):]
for i in range(len(attri_values_1)):
for j in range(len(list_headers)):
print Get_Match(attri_values_1[i],list_headers[j])
python为字符串提供了一个find
方法,您可以使用该方法为每个属性值迭代每个列表头。尝试使用此功能:
def Get_Match(search_space,search_string):
start_character = search_space.find(search_string)
if start_character == -1:
return "N/A"
else:
return search_space[(start_character + len(search_string)):]
for i in range(len(attri_values_1)):
for j in range(len(list_headers)):
print Get_Match(attri_values_1[i],list_headers[j])
我的答案是使用熊猫
import pandas as pd
# input data
list_headers = ['gene_id', 'gene_name', 'trans_id']
attri_values = [
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"'],
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'trans_id "scaffold_200001.1"', 'transcript_version "1"', 'exon_number "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200001.1.exon1"', 'exon_version "1"'],
['gene_id "scaffold_200002.1"', 'gene_version "1"', 'trans_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "3"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon3"', 'exon_version "1"']]
# process input data
attri_values_X = [dict([tuple(b.split())[:2] for b in a]) for a in attri_values]
# Create DataFrame with the desired columns
df = pd.DataFrame(attri_values_X, columns=list_headers)
# print dataframe
print df
输出
gene_id gene_name trans_id
0 "scaffold_200001.1" NaN NaN
1 "scaffold_200001.1" NaN "scaffold_200001.1"
2 "scaffold_200002.1" NaN "scaffold_200002.1"
没有熊猫也很容易。我已经给了你attri\u values\u X
,然后你就快到了,只需从你不想要的字典中删除键。我的答案是使用pandas
import pandas as pd
# input data
list_headers = ['gene_id', 'gene_name', 'trans_id']
attri_values = [
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"'],
['gene_id "scaffold_200001.1"', 'gene_version "1"', 'trans_id "scaffold_200001.1"', 'transcript_version "1"', 'exon_number "1"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200001.1.exon1"', 'exon_version "1"'],
['gene_id "scaffold_200002.1"', 'gene_version "1"', 'trans_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "3"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon3"', 'exon_version "1"']]
# process input data
attri_values_X = [dict([tuple(b.split())[:2] for b in a]) for a in attri_values]
# Create DataFrame with the desired columns
df = pd.DataFrame(attri_values_X, columns=list_headers)
# print dataframe
print df
输出
gene_id gene_name trans_id
0 "scaffold_200001.1" NaN NaN
1 "scaffold_200001.1" NaN "scaffold_200001.1"
2 "scaffold_200002.1" NaN "scaffold_200002.1"
没有熊猫也很容易。我已经给了你attri\u values\u X
,然后你就快到了,只需从你不想要的字典中删除键。我设法编写了一个函数,它将有助于解析你的数据。我试图修改您发布的原始代码,但使问题复杂的是您存储需要解析的数据的方式,无论如何我无法判断,以下是我的代码:
def searchHeader(title, values):
""""
searchHeader(title, values) --> list
*Return all the words of strings in an iterable object in which title is a substring,
without including title. Else write 'N\A' for strings that title is not a substring.
Example:
>>> seq = ['spam and ham', 'spam is awesome', 'Ham is...!', 'eat cake but not pizza']
>>> searchHeader('spam', attri_values)
['and', 'ham', 'is', 'awesome', 'N\\A', 'N\\A']
"""
res = []
for x in values:
if title in x:
res.append(x)
else:
res.append('N\A') # If no match found append N\A for every string in values
res = ' '.join(res)
# res = res.replace('"', '') You can use this for your code or use it after you call the function on res
res = res.split(' ')
res = [x for x in res if x != title] # Remove title string from res
return res
正则表达式在这种情况下也很方便。使用此函数解析数据,然后格式化结果以将表写入文件。此函数仅使用一个循环和一个列表理解,其中在代码中使用两个嵌套的循环和一个列表理解
将每个头字符串分别传递给函数,如下所示:
for title in list_headers:
result = searchHeader(title, attri_values)
...format as table...
...write to file...
如果可能的话,考虑从一个简单的列表移动到一个字典,用于<代码> ATTILIOVALUTION/CODE >,这样你就可以用它们的标题对字符串进行分组:
attri_values = {'header': ('data1', 'data2',...)}
在我看来,这比使用列表要好。还要注意,您正在代码中重写list
name,这不是一件好事,因为list
实际上是创建列表的内置类 我成功地编写了一个有助于解析数据的函数。我试图修改您发布的原始代码,但使问题复杂的是您存储需要解析的数据的方式,无论如何我无法判断,以下是我的代码:
def searchHeader(title, values):
""""
searchHeader(title, values) --> list
*Return all the words of strings in an iterable object in which title is a substring,
without including title. Else write 'N\A' for strings that title is not a substring.
Example:
>>> seq = ['spam and ham', 'spam is awesome', 'Ham is...!', 'eat cake but not pizza']
>>> searchHeader('spam', attri_values)
['and', 'ham', 'is', 'awesome', 'N\\A', 'N\\A']
"""
res = []
for x in values:
if title in x:
res.append(x)
else:
res.append('N\A') # If no match found append N\A for every string in values
res = ' '.join(res)
# res = res.replace('"', '') You can use this for your code or use it after you call the function on res
res = res.split(' ')
res = [x for x in res if x != title] # Remove title string from res
return res
正则表达式在这种情况下也很方便。使用此函数解析数据,然后格式化结果以将表写入文件。此函数仅使用一个循环和一个列表理解,其中在代码中使用两个嵌套的循环和一个列表理解
将每个头字符串分别传递给函数,如下所示:
for title in list_headers:
result = searchHeader(title, attri_values)
...format as table...
...write to file...
如果可能的话,考虑从一个简单的列表移动到一个字典,用于<代码> ATTILIOVALUTION/CODE >,这样你就可以用它们的标题对字符串进行分组:
attri_values = {'header': ('data1', 'data2',...)}
在我看来,这比使用列表要好。还要注意,您正在代码中重写list
name,这不是一件好事,因为list
实际上是创建列表的内置类 谢谢你的回答。使用字典会很复杂,因为这些只是大数据的一小部分。我认为简单的嵌套for循环可以解决这个问题。顺便说一句,我在
result=searchHeader(列出标题、属性值)`@everestial007我的坏!我应该将title
而不是list\u headers
传递给函数:result=searchHeader(title,attri\u value)
。这可能是深夜编写代码的后果吗:P?我理解太多地站在电脑前和/或昏昏欲睡的后果。顺便说一句,代码仍然不能为我解决这个问题。我试着改变一些东西,比如在x:
中改为if title:
我认为应该是if x.startswith(title)
原因是除非所有字符串都匹配,否则列表对列表的比较不会出现命中。我也尝试过改变其他事情,但没有运气。你能给我一个完整的工作例子吗那可能吗。请向上投票,让其他人也更加关注这个问题。@everestial007查看此代码以了解如何使用该函数,顺便说一句,我使用print
打印测试结果。您可以在将结果格式化为表后将其写入文件:。您只需将所提供函数的输出格式化为一个表,然后将其写入输出文件。@everestal007如果您一直在写表,请参见下面的。虽然它仍然为不匹配的字符串打印N/A,但我已经包含了N/A以满足zip
,zip
一直运行到其参数列表中最短的iterable,从而删除了其他元素;在我们的例子中,它从属性值中删除字符串值。请参阅zip
的文档以了解更多信息或运行帮助(zip)
。研究代码,你会发现它很容易,就像柠檬挤压一样!:)谢谢你的回答。使用字典会很复杂,因为这些只是大数据的一小部分。我认为简单的嵌套for循环可以解决这个问题。顺便说一句,我得到类型错误