2016-11-07 53 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))