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 也很优雅。
我有一个数据文件,其中列出了日期(由包含 .
的行表示)和名称后跟一个数字:
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 也很优雅。