2015-05-22 25 views
3

我列出日期(含有.线表示),名称后跟一个数字数据文件:Python的命令(S)以找到独特的名字在长长的名单

2015.05.22 
nameA 15 
nameB 32 
2015.05.20 
nameA 2 
nameC 26 

这个列表文件是相当(约97k线,每天增长),我想(很快)得到所有列出的唯一名称。在bash中,我可以这样做:

cat file.txt | awk '{print $1}' | grep -v '\.' | sort -u | awk 'NF' 

但我在Python中使用这些数据,我想知道是否有一种方法可以在Python中做同样的事情。显然,我可以简单地从python脚本中调用这个shell命令,但我更愿意学习这样做的'最佳实践'。

回答

1

这样做,基本上实现了相同的一组行为作为你的“壳牌”脚本的招:

过滤给定文件中的行;删除任何包含.的行;获取一组独特的数据;打印

例子:

from __future__ import print_function 

lines = (line.strip() for line in open("foo.txt", "r")) 
all_names = (line.split(" ", 1)[0] for line in lines if "." not in line) 
unique_names = set(all_names) 
print("\n".join(unique_names)) 

输出:

$ python foo.py 
nameC 
nameB 
nameA 
0

你可以做到这一切在短短的一个awk命令:

$ awk 'NF && $1!~/\./ {a[$1]} END {for (i in a) print i}' file 
nameC 
nameA 
nameB 

此检查有一些数据,其第一场不包含点的那些行。在这种情况下,它将数值存储在数组a[]中,稍后打印。

在Python中,你可以使用一个set()来存储数据,并防止重复:

for name in set([line.split()[0] for line in open('a') if line.split()[0] and "." not in line.split()[0]]): 
    print name 
0

该做的更详细的方法:

unique_results = set() 

with open("my file.txt") as my_file: 
    for line in my_file: 
     if "." not in line: 
      name = line.split(" ") 
      unique_results.add(name) 
1

只需使用re

>>> input_str = """ 
2015.05.22 
nameA 15 
nameB 32 
2015.05.20 
nameA 2 
nameC 26 
""" 
>>> import re 
>>> set(re.findall('[a-zA-Z]+', input_str)) 
set(['nameB', 'nameC', 'nameA']) 
>>> 
0

只需一行代码来实现这一目标(假设的Python 2.x的):

unique_names = {}.fromkeys([line.split()[0] for line in open("file.txt", "r") if "." not in line]).keys() 
print unique_names 

输出:

['nameB', 'nameC', 'nameA'] 
如果你想使输出像贝壳做

print "\n".join(unique_names) 

输出:

nameB 
nameC 
nameA 

如果名字的顺序无关紧要,python也很优雅。