如何用数字拆分混合字符串

时间:2015-12-30 17:19:32

标签: python string sorting file-io

我的文本文件中包含“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) ]

5 个答案:

答案 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

test.py

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的好处是它会按排序顺序添加它们,这会减轻你的负担,并且它是在线性时间内完成的。

example.txt中

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)

此代码段应该可以正常工作。这种排序称为自然排序,通常在字母数字的情况下使用。