2013-05-26 55 views
0

我試圖從多個打開的文件創建列表,存在一些問題。我需要爲每個文件創建兩個單獨的列表,現在我的代碼只爲迭代的最後一個文件創建兩個列表。建議修復,併爲'file_list'中的每個文件創建獨特的'sample_genes'和'sample_values'?在'for'循環中爲每個打開的文件創建單獨的列表

或者,從所有文件中爲'gene_names'創建單個統一列表,並從所有文件中爲'sample_values'創建單個統一列表也可以。

# Parse csv files for samples, creating lists of gene names and expression values. 
file_list = ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv'] 
des_list = ['a', 'b', 'c', 'd', 'e', 'f'] 
for idx, (f_in, des) in enumerate(zip(file_list, des_list)): 
    with open(f_in) as des: 
     cread = list(csv.reader(des, delimiter = '\t')) 
     sample_genes = [i for i, j in (sorted([x for x in {i: float(j) 
             for i, j in cread}.items()], key = lambda v: v[1]))]   
     sample_values = [j for i, j in (sorted([x for x in {i: float(j) 
          for i, j in cread}.items()], key = lambda v: v[1]))] 

# Compute row means. 
mean_values = [((a + b + c + d + e + f)/len(file_list)) for i, (a, b, c, d, e, f) in enumerate(zip(sample_1_values, sample_2_values, sample_3_values, sample_4_values, sample_5_values, sample_6_values))] 

# Provide proper gene names for mean values and replace original data values by corresponding means. 
sample_genes_list = [i for i in sample_1_genes, sample_2_genes, sample_3_genes, sample_4_genes, sample_5_genes, sample_6_genes] 

sample_final_list = [sorted(zip(sg, mean_values)) for sg in sample_genes_list] 

新的下面的代碼:從字典中拆包字典

# Parse csv files for samples, creating lists of gene names and expression values. 
file_list = ['CRPC_278.csv', 'PCaP_470.csv', 'CRPC_543.csv', 'PCaN_5934.csv', 'PCaN_6102.csv', 'PCaP_17163.csv'] 
full_dict = {} 
for path in file_list: 
    with open(path) as stream: 
      data = list(csv.reader(stream, delimiter = '\t')) 
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1]) 
    sample_genes = [i for i, j in data] 
    sample_values = [j for i, j in data] 
    full_dict[path] = (sample_genes, sample_values) 

結果顯示一些深層次的嵌套結構:

for key in full_dict: 
value = full_dict[key] 
for key in full_dict[key]: 
    for idx, items in enumerate(key): 
     print idx 
+0

第一個問題是:關於'des'變量名稱:在循環範圍中使用它兩次,首先解壓縮壓縮列表,然後下一次打開文件對象。另外:不要使用'file'作爲變量名稱,因爲它是python中的一個內置短語。你也有一個語法問題:'{i:float(j)...' - 什麼是花括號?和':'?你想做什麼? –

+0

@PeterVaro:'{a:b for ...}'是一個字典理解,例如,'{i:i for i in range(3)}'產生'{0:0,1:1,2:2 }'。當然,在OP的問題中的使用是很奇怪的...... – torek

+0

這是一個嵌套的列表理解內嵌的列表解析等,驗證以提供正確的輸出,代碼是正確的。修改上面的文件對象名稱。 – user2277435

回答

3

我不確定你的csv文件中有什麼,但你正在做一些冗餘的工作,和一些毫無意義的工作。讓我們打破這些了一點:

for idx, (f_in, des) in enumerate(zip(file_list, des_list)): 

idx不會出現在循環體可言,所以你不需要enumerate

des確實出現在列表中的主體,但其第一次出現是在構建體:

with open(f_in) as des: 

使得循環內的一個是不同的des,不同於打開文件的流。所以推測你也不需要zip。刪除這兩個,你可能只是做:

for f_in in file_list: 

接下來,你讀一次文件(list(csv.reader(...)),這是罰款。結果保存在名稱cread中。

然後,你有兩個列表解析運行在sorted的結果上,這個結果本身給出了將.items()應用於字典理解的結果的列表理解運行的結果。外列表解析的要點是從列表中提取一個或另一個項目:第一個i,然後j,從[... for i, j in ...]

這可能是適當的根據有什麼sorted內發生的事情,讓我們來看看是:

sorted(..., key = lambda v: v[1]) 

這意味着列表元素本身必須是指數能和你被排序第二項(當然第一項是v[0])。

當您按第二項進行排序,然後取第一項並放棄第二項時,它至少不是多餘的。但是,如果您按第二項進行排序,然後取第二項並丟棄第一項,則可以簡單地取第二項,然後進行排序並完成。 (但是,在我們走到那麼遠之前,我們再來檢查一下:-))

最後,讓我們看看字典理解和.items()調用。該dictcomp本身,在這兩種情況下:

{i: float(j) for i, j in cread} 

想必您的CSV文件必須給你對,無論是在第一部分可以用作鍵,而無論是在第二部分是轉換爲float。因此,讓我們來看一個簡單的字典,是,說,字符串和浮動兩個關鍵 - 值對:

{'a': 2.71828, 'b': 3.14159} 

和應用.items()

>>> {'a': 2.71828, 'b': 3.14159}.items() 
[('a', 2.71828), ('b', 3.14159)] 

而是組成一個字典和摺疊它回到2元組元組列表中,你可以使用列表理解來構造2元組元組。讓我們來測試一下:

>>> cread = [['a', '2.71828'], ['b', '3.14159']] 
>>> [(i, float(j)) for i, j in cread] 
[('a', 2.71828), ('b', 3.14159)] 

現在我們可以通過它的第二個元素對這個事物進行一次排序。我們可以使用sorted,或者製作一份清單並對其進行排序,但一旦完成,我們就保存它。在我們開始之前,我已經選擇了一個糟糕的設定值,因爲它們是已經排序,讓我們添加一對到CREAD是各種不同的:

>>> cread.append(['c', '0']); print cread 
[['a', '2.71828'], ['b', '3.14159'], ['c', '0']] 
>>> by_second = sorted([(i, float(j)) for i, j in cread], key = lambda v: v[1]) 
>>> by_second 
[('c', 0.0), ('a', 2.71828), ('b', 3.14159)] 

救這個排序的事情,我們現在可以得到sample_genes和sample_values通過原來的list-comprehension-to-pick-item列表。我也會更改一些名字:

for path in file_list: 
    with open(path) as stream: 
     data = list(csv.reader(stream, delimiter = '\t')) 
    data = sorted([(i, float(j)) for i, j in data], key = lambda v: v[1]) 
    sample_genes = [i for i, j in data] 
    sample_values = [j for i, j in data] 

下一步當然是以某種方式保存這些樣本。想必你要爲使用idxdes_list他們的名字,但似乎通過CSV路徑名給他們指標更直接:

somedict[path] = (sample_genes, sample_values) 

其中somedict最初是一個空字典(進入for循環之前創建)。儘管如此,在某些時候,開始考慮正確的數據結構並創建一個類是合理的。

+0

目前看起來相當不錯。我修改了上面的代碼。現在的問題是,查看詞典中的詞典,每個文件有6個頂級索引,很好。但下面是每個子項的奇怪數量,更驚人,不同數量。有些東西仍然不正確,因爲每個文件都給出了相同的29,000個名稱,每個csv的值。無論如何,非常感謝,我會標記爲正確的。對於其餘問題的任何進一步意見將不勝感激。 – user2277435

+0

''enumerate'在字典上遍歷鍵:'爲我,枚舉中的項({'key1':1.0,'key2':1.5}):打印我,item'打印'0 key2'然後'1 key1 '。您可以通過以下方式訪問字典中的值:「for key in adict:value = adict [key]; ......或各種詞典訪問器之一('.items','.keys','.values'等)。 – torek

+0

'print full_dict'似乎確實給出了完整的正確輸出,只需瞭解字典是如何構造的,以便從下一步調用右數據集中的值。 – user2277435

0

不知道如果我看到這個問題,可以」你只是做

sample_genes[idx] = [i for i, j in (.... 
sample_values[idx] = [j for i, j in (.... 

sample_genes[des]如果您更喜歡命名屬性?

+0

它看起來會工作,但會拋出'IndexError:列表分配索引超出範圍'的錯誤。我懷疑是因爲有大量的指數。 – user2277435

相關問題