Python-使用可变数量的键/值制作字典

问题描述

好的,标题有点混乱,但让我详细说明。

Java中的某些方法一个叫做varargs的有用的东西,它允许在方法中使用不同数量的参数。看起来像这样:

void method(String... args) {
    for (String arg : args) {
        // Todo
    }
}

我正在尝试通过一门课程学习Python,其中一项任务是要求我获取一个CSV文件,该文件的顶部带有 variable (可变)数量的字符串,这些字符串表示DNA中重复序列。股。这是一个示例:

name,AGATC,AATG,TATC
Alice,2,8,3

但是,他们还提供了不同的CSV文件,这些文件具有不同数量的DNA序列供检查,如下例所示:

name,TTTTTTCT,TCTAG,GATA,TATC,GAAA,TCTG
Jason,15,49,38,5,14,44,12

(数字等于上述链中重复的上述DNA序列的数量。因此Jason在该链中有15个AGATC重复)

我想使用Dictionary变量在其中存储名称及其所有重复项。但是,由于我事先不知道需要检查多少个DNA序列,因此必须在编写词典时考虑到任意数量的这些序列。 是否可以在Python varargs中使用类似于Java Dictionary的方式?

我想要的输出格式是将一群人及其在DNA数据库中的重复信息转换为一个列表,该列表包含一个相当于每个人的字典。因为CSV文件可以包含可变数量的DNA序列(如上所示),所以我想让每个人的Dictionary都以其名字作为他们的第一个键,然后在CSV文件中为每个DNA序列添加更多的键。这是一个遵循上述CSV文件摘要的示例: {"name": "Jason","seq1": 15,"seq2": 49,"seq3": 38,"seq4": 5,"seq5": 14,"seq6": 4,"seq7": 14,"seq8": 12}

解决方法

您可以使用*args来获取包含所有参数的列表

def my_seq(*args): 
    for arg in args: 
        print (arg)
   
my_seq('a','b','c','d') 
,

所有 Python字典具有可变数量的项,因为它们是可变的,所以这有点XY problem,但是要获得所需的内容,可以使用csv.DictReader(如Thierry Lathuille commented)。

让我们打电话给您的第一个示例example1.csv

name,AGATC,AATG,TATC
Alice,2,8,3

要阅读它,您可以执行以下操作:

import csv

with open('example1.csv') as f:
    rows = list(csv.DictReader(f))

print(rows)
# -> [{'name': 'Alice','AGATC': '2','AATG': '8','TATC': '3'}]

数字不会自动转换为整数,但是您可以使用字典理解:

rows = [
    {k: v if k == 'name' else int(v) for k,v in row.items()}
    for row in rows
    ]
print(rows)
# -> [{'name': 'Alice','AGATC': 2,'AATG': 8,'TATC': 3}]

请注意,DNA序列本身可能比'seq1''seq2'等更有用。例如,如果您以rows2的形式读取其他CSV,则可以在按键上执行类似集合的操作:

>>> alice = rows[0]
>>> jason = rows2[0]
>>> len(alice.keys() - jason.keys())  # How many keys are unique to Alice?
0
>>> jason.keys() - alice.keys()  # What keys does Jason have that Alice doesn't?
{'TCTAG','GATA','TCTG','TTTTTTCT','GAAA'}

如果您想真正变得更高级,可以使用Pandas DataFrame。这只是一个简短的示例,因为我自己对它不是很熟悉:)

import pandas as pd

files = 'example2.csv','example1.csv'  # Note the order
dfs = [pd.read_csv(f,index_col="name") for f in files]
df = pd.concat(dfs,sort=False)
df = df.astype('Int64')  # allow ints and NaN in the same column

print(df)

输出:

       AGATC  TTTTTTCT  AATG  TCTAG  GATA  TATC  GAAA  TCTG
name                                                       
Jason     15        49    38      5    14    44    14    12
Alice      2       NaN     8    NaN   NaN     3   NaN   NaN