2012-04-27 43 views
-1

我需要你的帮助。文本文件列表

我有一个文本文件包含列表行,每行代表一个项目列表。我需要提取频率大于等于2的所有项目并将它们输出到另一个文件中。以下是一个示例。

['COLG-CAD-406', 'CSAL-CAD-030', 'COLG-CAD-533', 'COLG-CAD-188'] 

['COLG-CAD-188'] 

['CSAL-CAD-030'] 

['EPHAG-JAE-004'] 

['COLG-CAD-188', 'CEM-SEV-004'] 

['COL-CAD-188', 'COLG-CAD-406'] 

输出应该是

['COLG-CAD-406'], 2 

['CSAL-CAD-030'], 2 

['COLG-CAD-188'], 3 

,并以此类推,直到文件的末尾

非常感谢您的帮助提前。

+0

什么与所有在你的问题 “在此处输入代码”?什么“频率”意味着你的问题? – 2012-04-27 18:08:42

+0

你的线路编号五不是很好形成 – joaquin 2012-04-27 19:11:11

+0

'CSAL-CAD-030'只出现两次,所以我改变了你的例子输出 – jamylak 2012-04-28 13:57:16

回答

0

这是一个完整的脚本,它正是你想要什么,使用正则表达式:

from collections import defaultdict 
import re 

myarch = 'C:/code/test5.txt' #this is your archive 
mydict = defaultdict(int) 

with open(myarch) as f: 
    for line in f: 
     codes = re.findall("\'(\S*)\'", line) 
     for key in codes: 
      mydict[key] +=1 

out = [] 
for key, value in mydict.iteritems(): 
    if value > 1: 
     text = "['%s'], %s" % (key, value) 
     out.append(text) 

#save to a file 
with open('C:/code/fileout.txt', 'w') as fo: 
    fo.write('\n'.join(out)) 

这可以简化为:

from collections import defaultdict 
import re 

myarch = 'C:/code/test5.txt' 
mydict = defaultdict(int) 

with open(myarch) as f: 
    for line in f: 
     for key in re.findall("\'(\S*)\'", line): 
      mydict[key] +=1 

out = ["['%s'], %s" % (key, value) for key, value in mydict.iteritems() if value > 1] 

#save to a file 
with open('C:/code/fileout.txt', 'w') as fo: 
    fo.write('\n'.join(out)) 
+0

非常感谢。真的这是我想要的,但我需要一些修改,因为原始文件包含像这样的另一列1298962762.0 ['EPHAG-JAE-004'] 1298962802.0 ['CEM-SEV-003','CEM-SEV-004']我需要打印相同的东西,但保留包含数字的第一列。这是最终的输出1298962762.0 CSAL-CAD-030 2谢谢 – 2012-04-28 07:20:09

+0

@saiedsalah你不应该在评论中改变你的规格。我的回答是回答你目前的帖子。您可以根据新的要求修改您的帖子(在很多人回答您的初始条件后很奇怪),或者您对这些回答投票并提出新问题。 – joaquin 2012-04-28 17:46:23

2

什么:

for x in f.readlines(): 
    words = ast.literal_eval(x) 
    count = {} 
    for w in words:   
     count[w] = count.get(w, 0) + 1 
    for word, freq in count.iteritems(): 
     if freq >= 2: 
      print word, freq 

其中f是您的文件

+1

'words = ast.literal_eval(x)'将自然地解析每一行,而不需要重新实现列表解析 – Boud 2012-04-27 18:27:12

+0

@Boud good呼叫。改变我的答案... – Ord 2012-04-27 18:28:55

+0

非常感谢。但它没有打印任何东西,我不知道为什么? – 2012-04-28 08:33:01

0

如果您正在使用python 2.7及以上,这种输入(称为list1.txt):

['COLG-CAD-406', 'CSAL-CAD-030', 'COLG-CAD-533', 'COLG-CAD-188'] 
['COLG-CAD-188'] 
['CSAL-CAD-030'] 
['EPHAG-JAE-004'] 
['COLG-CAD-188', 'CEM-SEV-004'] 
['COLG-CAD-188', 'COLG-CAD-406'] 

和这条巨蟒程序:

from collections import Counter 
import ast 

cnt = Counter() 

with open("list1.txt") as lfile: 
    for line in lfile: 
     # eval() could lead to python code injection so use literal_eval 
     # the result is a list that we can directly use to update cnt keys 
     cnt.update(ast.literal_eval(line)) 

for k, v in iter(cnt.items()): 
    if v>=2: 
     print("%s: %d"% (k, v)) 

你得到你想要的东西:

CSAL-CAD-030: 2 
COLG-CAD-406: 2 
COLG-CAD-188: 4 
+1

[eval()将允许恶意数据危害整个系统,杀死你的猫,吃掉你的狗,并让你的妻子爱上它。](http://stackoverflow.com/questions/661084/security-of-pythons-eval -on-untrusted-strings) – joaquin 2012-04-27 19:21:12

+0

非常感谢。但是当我应用上面的代码时,我从集合中收到以下错误导入计数器 ImportError:无法导入名称Counter。我不知道为什么,请你帮我解决这个问题。非常感谢 – 2012-04-28 07:40:26

+0

@saiedsalah:正如我在答案中所写的那样:至少需要[python version 2.7](http://docs.python.org/library/collections.html)。如果你用旧版本运行这个,你会得到这个错误。 – 2012-04-28 07:54:06

0

输入:

['COLG-CAD-406', 'CSAL-CAD-030', 'COLG-CAD-533', 'COLG-CAD-188'] 

['COLG-CAD-188'] 

['CSAL-CAD-030'] 

['EPHAG-JAE-004'] 

['COLG-CAD-188', 'CEM-SEV-004'] 

['COL-CAD-188', 'COLG-CAD-406'] 

输出

>>> from collections import Counter 
>>> from ast import literal_eval 
>>> with open('input.txt') as f: 
     c = Counter(word for line in f if line.strip() for word in literal_eval(line)) 


>>> print '\n'.join('{0}, {1}'.format([word],freq) for word,freq in c.iteritems() if freq >= 2) 
['CSAL-CAD-030'], 2 
['COLG-CAD-406'], 2 
['COLG-CAD-188'], 3