Python 个用于在长列表中查找唯一名称的命令

Python command(s) to find unique names in long list

我有一个数据文件,其中列出了日期(由包含 . 的行表示)和名称后跟一个数字:

2015.05.22
nameA 15
nameB 32
2015.05.20
nameA 2
nameC 26

此列表文件很长(约 97k 行并且每天都在增长),我想(快速)列出所有唯一名称。在 bash 我可以做到:

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

但我在 Python 中使用这些数据,我想知道是否有办法在 Python 中做同样的事情。显然,我可以从 python 脚本中简单地调用此 shell 命令,但我宁愿学习 'best practices' 执行此操作的方法。

您只需一个 awk 命令即可完成所有这些:

$ awk 'NF && !~/\./ {a[]} 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

这将实现基本上实现与您的 "Shell" 脚本相同的一组行为的技巧:

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

示例:

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

更详细的方法:

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)

只需使用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'])
>>> 

只需一行代码即可实现(假设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']

如果你想像 shell 那样输出:

print "\n".join(unique_names)

输出:

nameB
nameC
nameA

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