2011-05-19 4 views
4

UPDATE: Я должен был указать это раньше, но не все имена просто плавают. Например, некоторые из них «с префиксом» с «YT». Например, «YT1.1. Итак, у вас есть одна и та же проблема. YT1.9 < YT1.11 должен быть правдой. Я действительно удивлен, что сравнение строк не удалось ....сравнить две строки python, содержащие числа

hello, Это должно быть довольно простой вопрос, но я не могу найти ответ. Я бы хотел отсортировать группу из XL-листов по имени. Каждое из имен - это числа, но так же, как «разделы» учебника нумеруются, что означает раздел 4,11 приходит после 4.10, которые оба пришли после того, как 4,9 и 4,1, я думал, просто сравнивая эти цифры как строка будет делать, но я получаю следующее:.

>>> s1 = '4.11' 
>>> s2 = '4.2' 
>>> s1> s2 
False 
>>> n1 = 4.11 
>>> n2 = 4.2 
>>> n1 > n2 
False 

как я могу сравнить эти два значения таким образом, что 4,11 больше, чем 4.2?

ответ

9

Преобразования имен наборов целых чисел и сравнить кортежи:

def splittedname(s): 
    return tuple(int(x) for x in s.split('.')) 

splittedname(s1) > splittedname(s2) 

Update: Так как ваши имена, видимо, могут содержать другие символы, кроме цифр, вам нужно проверить ValueError и оставить все значения которые не могут быть преобразованы в Интс без изменений:

import re 

def tryint(x): 
    try: 
     return int(x) 
    except ValueError: 
     return x 

def splittedname(s): 
    return tuple(tryint(x) for x in re.split('([0-9]+)', s)) 

чтобы отсортировать список имен, используйте splittedname в качестве ключевой функции sorted:

>>> names = ['YT4.11', '4.3', 'YT4.2', '4.10', 'PT2.19', 'PT2.9'] 
>>> sorted(names, key=splittedname) 
['4.3', '4.10', 'PT2.9', 'PT2.19', 'YT4.2', 'YT4.11'] 
+0

Отличный ответ. Простой и эффективный. – dkamins

+0

не нужно преобразовывать в int even. – marr75

-2

Если вы знаете, что они являются действительными числами [*], просто:

>>> float(s1) > float(s2) 
True 

[*] В противном случае, будьте готовы справиться с поднятым ValueError.

+4

Неправильно. 4.11 float <4.2, но должен прийти после этого (11> 2). – dkamins

+0

Это предполагает, что числа являются действительными поплавками. – Falmarri

+1

Нет, это предполагает, что ОП задал другой вопрос. Действительные поплавки - это предположение. – marr75

1

Это не встроенный метод, но он должен работать:

>>> def lt(num1, num2): 
...  for a, b in zip(num1.split('.'), num2.split('.')): 
...   if int(a) < int(b): 
...    return True 
...   if int(a) > int(b): 
...    return False 
...  return False 
... 
... lt('4.2', '4.11') 
0: True 

Это может быть очищен, но это дает вам суть.

1

То, что вы ищете, называется «естественной сортировкой». Это противоречит «лексикографической сортировке». Существует несколько рецептов, которые делают это, поскольку точный вывод того, что вы хотите, зависит от реализации. Быстрый поиск Google дает это (примечание * это не мой код, ни я тестировал):

import re 

def tryint(s): 
    try: 
     return int(s) 
    except: 
     return s 

def alphanum_key(s): 
    """ Turn a string into a list of string and number chunks. 
     "z23a" -> ["z", 23, "a"] 
    """ 
    return [ tryint(c) for c in re.split('([0-9]+)', s) ] 

def sort_nicely(l): 
    """ Sort the given list in the way that humans expect. 
    """ 
    l.sort(key=alphanum_key) 

http://nedbatchelder.com/blog/200712.html#e20071211T054956

0

использование s1.split(".") создать список элементов до и после запятой, то вроде список списков, например:

import random 
sheets = list([str(x), str(y)] for x in xrange(1, 5) for y in xrange(0,99)) 
print sheets 
#sheets in order 
random.shuffle(sheets) 
print sheets 
#sheets out of order 
sheets.sort() 
print sheets 
#sheets back in order 

Таким образом, вы реализация может быть:

#assume input sheets is a list of the worksheet names 
sheets = list(x.split(".") for x in input_sheets) 
sheets.sort() 
Смежные вопросы