我的文本文件中包含“Test DATA_g004,Test DATA_g003,Test DATA_g001,Test DATA_g002”。
是否可以在没有“Test DATA_”字样的情况下对其进行排序,这样数据的排序方式就像g001,g002,g003等?
我尝试了.split("Test DATA_")
方法,但它不起作用。
def readFile():
#try block will execute if the text file is found
try:
fileName = open("test.txt",'r')
data = fileName.read().split("\n")
data.sort (key=alphaNum_Key) #alternative sort function
print(data)
#catch block will execute if no text file is found
except IOError:
print("Error: File do not exist")
return
#Human sorting
def alphaNum(text):
return int(text) if text.isdigit() else text
#Human sorting
def alphaNum_Key(text):
return [ alphaNum(c) for c in re.split('(\d+)', text) ]
答案 0 :(得分:7)
您可以使用re
。
import re
x="Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002"
print sorted(x.split(","),key= lambda k:int(re.findall("(?<=_g)\d+$",k)[0]))
输出:[' Test DATA_g001', ' Test DATA_g002', ' Test DATA_g003', 'Test DATA_g004']
答案 1 :(得分:4)
检索以g
开头的所有字符串,然后使用sorted
>>> s = "Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002, "
>>> sorted(re.findall(r'g\d+$', s))
['g001', 'g002', 'g003', 'g004']
另一种方法是仅使用内置方法:
>>> l = [x.split('_')[1] for x in s.split(', ') if x]
>>> l
['g004', 'g003', 'g001', 'g002']
>>> l.sort()
>>> l
['g001', 'g002', 'g003', 'g004']
答案 2 :(得分:3)
是的,你可以。您可以按每个测试子字符串中的最后3位数进行排序:
# The string to be sorted by digits
s = "Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002"
# Create a list by splitting at commas, sort the last 3 characters of each element in the list as `ints`.
l = sorted(s.split(','), key = lambda x: int(x[-3:]))
print l
# [' Test DATA_g001', ' Test DATA_g002', ' Test DATA_g003', 'Test DATA_g004']
如果您对l
的元素很重要,那么您会想要修剪它们,但这对于以3位数字结尾的所有Test
都有效。
如果您不想Test DATA_
,可以执行以下操作:
# The string to be sorted by digits
s = "Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002"
# Create a list by taking the last 4 characters of sorted strings with key as last 3 characters of each element in the list as `int`s.
l = sorted((x[-4:] for x in s.split(',')), key = lambda x: int(x[-3:]))
print l
# ['g001', 'g002', 'g003', 'g004']
如果您的数据格式正确(即g
后跟3位数字),这将非常有效。否则,请使用任何其他发布的答案中的正则表达式。
另一种选择是在阅读时将字符串推送到PriorityQueue
:
from Queue import PriorityQueue
q = PriorityQueue()
with open("example.txt") as f:
# For each line in the file
for line in f:
# Create a list from the stripped, split-at-comma string
for s in line.strip().split(','):
# Push the last four characters of each element in the list into the pq
q.put(s[-4:])
while not q.empty():
print q.get()
使用PQ的好处是它会按排序顺序添加它们,这会减轻你的负担,并且它是在线性时间内完成的。
Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002
输出:
13:25 $ python test.py
g001
g002
g003
g004
答案 3 :(得分:2)
听起来你想要“自然分类”。从https://stackoverflow.com/a/4836734/3019689复制的以下内容可能会执行此操作。
import re
def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
然而,你一直说你想要排序“没有Test DATA_
”,这表明你不是在讲述整个故事。如果每个时间确实是Test DATA_
,那么它不会影响排序:有或没有它的排序;没关系。我敢打赌你真的很担心这个字符串前缀实际上因文件名而异,你想要完全忽略它,只关注数字部分。如果是这种情况,您可以将else None
替换为上面列表中的else text.lower()
。
答案 4 :(得分:0)
import re
def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [ convert(c) for c in re.split('(\d+)', key) ]
return sorted(l, key = alphanum_key)
此代码段应该可以正常工作。这种排序称为自然排序,通常在字母数字的情况下使用。