2016-11-07 63 views
0

我有以下的文本文件試圖組值:循環通過文件,並通過按鍵

1 cdcdm 
1 dhsajdhsa 
2 ffdm 
2 mdff 
3 ccdfm 
3 cdmfc 
3 fmdcc 

我的目標是輸出看起來像這樣:

1 : cdcdm, dhsajdhsa 
2 : ffdm, mdff 
3 : ccdfm, cdmfc, fmdcc 

我寫的下面的代碼,但由於某種原因,我沒有得到預期的輸出。

value_list = '' 
cur_key = None 
key = None 
f = open('example.txt', 'r') 
for line in f.readlines(): 
    try: 
     key, value = line.split() 
     key = key.strip() 
     value = value.strip() 
     if cur_key == key: 
      value_list = value_list + "," + value 
     else: 
      if cur_key: 
       print(cur_key + ":" +value_list) 
       cur_key = key 
       value_list = '' 
      else: 
       cur_key = key 
    except Exception as e: 
     continue 

我得到以下輸出:

1:,dhsajdhsa 
2:,mdff 

如何修改我的代碼得到這個工作?

感謝,

芒果

回答

2

一種最小變化實現可能看起來像這樣

with open('example.txt', 'r') as f: 
    cur_key = None 
    value_list = [] 
    for line in f.readlines(): 

     key, value = line.split() 
     value = value.strip() 

     if not cur_key: 
      cur_key = key 

     if cur_key == key:  
      value_list.append(value) 
     else: 
      print(cur_key + ":" + ', '.join(value_list)) 
      cur_key = key 
      value_list = [value] 
    print(cur_key + ":" +', '.join(value_list)) 

輸出:

1:cdcdm, dhsajdhsa 
2:ffdm, mdff 
3:ccdfm, cdmfc, fmdcc 

所以我們需要確保cur_key有第一次迭代的值。所以如果不是None就設置它。同樣,當我們找到新密鑰時,我們不應該將value_list重置爲空白。它應該被設置爲在該行讀取的值,所以留置權不會被跳過。同樣爲了抓住最後的組羣線,我們應該在最後在循環外再次打印值。

1

使用itertools.groupby

import itertools 

with open('example.txt') as f: 
    for key, strings in itertools.groupby(f, lambda s: s.strip()[0]): 
     print('{}: {}'.format(
      key, ', '.join(s.split(None, 1)[1].strip() for s in strings))) 

下面是根據你的代碼的答案:

value_list = [] 
cur_key = None 
f = open('example.txt', 'r') 

for line in f: 
    key, value = line.split() 
    key = key.strip() 
    value = value.strip() 
    if cur_key == key or cur_key is None: 
     value_list.append(value) 
    else: 
     print('{}: {}'.format(cur_key, ','.join(value_list))) 
     value_list = [value] 
    cur_key = key 

if value_list: 
    print('{}: {}'.format(cur_key, ','.join(value_list))) 
+0

有沒有辦法通過修改我現有的代碼來實現它?我打算以特定的方式解決它。 – mangodreamz

0

我建議拋出該走並使用collections.defaultdict。然後你就可以值添加到列表中相應的按鍵和打印時,即可大功告成完成的詞典:

import collections 

d = collections.defaultdict(list) 

with open('example.txt') as f: 
    for line in f: 
     k,v = line.split() 
     d[k].append(v.strip()) 

for k,v in sorted(d.items()): 
    print('{} : {}'.format(k, ', '.join(v))) 
+0

我想解決方案是無狀態的。有沒有辦法解決它,而不記得整個字典? – mangodreamz

+0

@mangodreamz:這就是'groupby'答案的作用。 – ShadowRanger

0

我也相信有更好的方法來做到這一點,但如果你真的想堅持基礎知識,至少使用列表而不是串聯文本。這是你的代碼的另一個版本,只需稍作更改:

lists = [] 
cur_key = None 
key = None 
f = open('example.txt', 'r') 
for line in f.readlines(): 
    try: 
     key, value = line.split() 
     key = key.strip() 
     value = value.strip() 
     if cur_key != key: 
      if(cur_key): 
       lists.append(value_list) 
      value_list = [] 
      cur_key = key 
     value_list.append(value) 
    except Exception as e: 
     continue 
lists.append(value_list) 

for i,l in enumerate(lists): 
    print(str(i+1) + ' : ' + ', '.join(l))