2015-12-30 28 views
5

"DATA_g004'ü Sınama, DATA_g003'ü Sınama, DATA_g001'i Sınama, DATA_g002'yi Sınama" başlıklı bir metin dosyasında veri var.Karışık bir dizeyi sayılarla bölme

"Test DATA_" sözcüğü olmaksızın sınıflandırmak mümkün mü, veriler g001, g002, g003 vb. Gibi sıralanacak mı?

.split("Test DATA_") yöntemini denedim ancak çalışmaz.

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

cevap

7

Bunu re kullanarak yapabilirsiniz.

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

Çıktı: Evet, yapabilirsin [' Test DATA_g001', ' Test DATA_g002', ' Test DATA_g003', 'Test DATA_g004']

+1

sıralama fucntion çalışıyor. Ancak ben sadece "g001" sıralamakta sorun yaşıyorum Temelde "Test DATA_" dizesi olmadan verileri nasıl sıralamak için? –

+0

@Aurora_Titanium (x.replace ('TestData', '') xs için – Caridorc

+0

@Aurora_Titanium 'g_' – vks

3

. Sen her test alt dize içinde son 3 hane tarafından sıralayabilirsiniz:

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

Bunu sizin için önemli ise l unsurlarını kırpmak isteyeceksiniz, ancak bu 3 basamaklı biten tüm Test s için çalışacaktır. Eğer Test DATA_ istemiyorsanız

, bunu yapabilirsiniz: Veri iyi biçimli ise

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

(yani 3 basamaklı ardından g), bu oldukça iyi çalışacaktır. Aksi takdirde, gönderilen diğer cevaplardan herhangi birini kullanın. Bunları okurken


diğer alternatif bir PriorityQueue dizeleri bas etmektir:

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() 
bir PQ kullanmanın yararı sıralı sırayla katacak olmasıdır

Yükünüzü alır ve doğrusal zamanda yapılır.

Test DATA_g004, Test DATA_g003, Test DATA_g001, Test DATA_g002 

Ve çıkışını example.txt:

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

Böyle basit ve normal görünümlü veriler için 're' üzerinde dilimleme kullanımınızı takdir ediyorum. Bence cevabı ve OP'nin eksikliğini, daha net hale getirdiğini düşünüyorum. –

5

başka yolu tüm dizeleri g ile başlayan Al ve ardından 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'] 

listeyi sıralamak, etmektir Yalnızca yerleşik yöntemler kullanı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

Çok hoş bir çözüm. Zarif ve temiz. – erip

2

"Doğal sıralama" istediğiniz gibi görünüyor. Aşağıdaki, https://stackoverflow.com/a/4836734/3019689 kopyalanabilir, bunu yapabilir.

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) 

Ancak, size bütün hikayeyi söylemediğin bana gösteriyor "Test DATA_ olmadan" sıralamak istiyorum söylüyorsun. Tam olarak Test DATA_her zamanında olsaydı, sıralamayı etkilemezdi: sırala veya onsuz sırala; önemli değil.Bahse girerim bu dize ön ekinin dosya adından dosya ismine değiştiğinden ve tamamen sayısal parçaya odaklanmadan tamamen yok saymak istediğinizden gerçekten endişeleniyorsunuz. Bu durumda, yukarıdaki listede else text.lower() için else None yerine kullanabilirsiniz.