2015-12-30 17 views
5

Tôi có dữ liệu trong tệp văn bản chứa "Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002".Cách chia chuỗi hỗn hợp với số

Có thể sắp xếp nó mà không có từ "Kiểm tra DATA_" để dữ liệu sẽ được sắp xếp như g001, g002, g003, v.v ... không?

Tôi đã thử phương pháp .split("Test DATA_") nhưng không hoạt động.

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) ] 

Trả lời

7

Bạn có thể thực hiện việc này bằng cách sử dụng 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])) 

Output: [' Test DATA_g001', ' Test DATA_g002', ' Test DATA_g003', 'Test DATA_g004']

+1

Fucntion sắp xếp hoạt động tốt. Tuy nhiên tôi đang gặp rắc rối chỉ cần phân loại "g001" Về cơ bản làm thế nào để sắp xếp dữ liệu mà không có chuỗi "Test DATA_"? –

+0

@Aurora_Titanium (x.replace ('TestData', '') cho x trong xs – Caridorc

+0

@Aurora_Titanium tôi đã sắp xếp dựa trên khóa 'số nguyên' ở cuối sau' g_' – vks

3

Vâng, bạn có thể. Bạn có thể sắp xếp theo 3 chữ số cuối cùng trong mỗi chuỗi thử nghiệm:

# 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'] 

Bạn sẽ muốn để cắt các phần tử của l nếu đó là quan trọng với bạn, nhưng điều này sẽ làm việc cho tất cả Test s kết thúc bằng 3 chữ số.

Nếu bạn không muốn Test DATA_, bạn có thể làm điều này:

# 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'] 

Nếu dữ liệu của bạn được tốt được hình thành (ví dụ: g tiếp theo là 3 chữ số), điều này sẽ làm việc khá tốt. Nếu không, hãy sử dụng regex từ bất kỳ câu trả lời nào được đăng khác.


lựa chọn khác là để đẩy chuỗi thành một PriorityQueue khi bạn đọc chúng:

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() 

Lợi ích của việc sử dụng một PQ là nó sẽ thêm chúng theo thứ tự sắp xếp , lấy gánh nặng của bạn, và nó được thực hiện trong thời gian tuyến tính.

example.txt

Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002 

Và kết quả:

13:25 $ python test.py 
g001 
g002 
g003 
g004 
+1

Tôi đánh giá cao việc bạn sử dụng việc cắt bớt 're' cho dữ liệu đơn giản và bình thường như vậy. Tôi nghĩ rằng nó làm cho câu trả lời, và những gì OP đã mất tích, rõ ràng hơn. –

5

Lấy tất cả các chuỗi bắt đầu với g và sau đó sắp xếp danh sách với 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'] 

Một cách khác, là để chỉ sử dụng các phương pháp tích hợp sẵn:

>>> l = [x.split('_')[1] for x in s.split(', ') if x] 
>>> l 
['g004', 'g003', 'g001', 'g002'] 
>>> l.sort() 
>>> l 
['g001', 'g002', 'g003', 'g004'] 
+3

Giải pháp rất đẹp. Thanh lịch và sạch sẽ. – erip

2

Có vẻ như bạn muốn "phân loại tự nhiên". Sau đây, được sao chép từ https://stackoverflow.com/a/4836734/3019689, có thể làm điều đó.

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) 

Tuy nhiên, bạn tiếp tục nói rằng bạn muốn sắp xếp "không có Test DATA_" cho tôi biết bạn không kể toàn bộ câu chuyện. Nếu đúng theo nghĩa là Test DATA_cứ mỗi thời gian, nó sẽ không ảnh hưởng đến sắp xếp: sắp xếp có hoặc không có nó; nó sẽ không thành vấn đề.Tôi đặt cược bạn đang thực sự lo lắng về thực tế là tiền tố chuỗi này thực sự thay đổi từ tên tập tin vào tên tập tin, và bạn muốn bỏ qua nó hoàn toàn bất cứ điều gì nó và chỉ tập trung vào phần số. Trong trường hợp này, bạn có thể thay thế else None cho else text.lower() trong danh sách ở trên.

Các vấn đề liên quan