2015-01-27 2 views
2

Привет Я пытаюсь создать список максимального значения уникальной строки в списке.Максимальное значение уникальной строки в списке

пример:

a = ['DS10.json', 'DS11.json', 'DT4.json', 'DT5.json', 'DT6.json', 'CJ6.json', 'CJ7.json'] 

должен вернуть мне список из следующих действий:

['DS11.json', 'DT6.json', 'CJ7.json'] 

Я попытался следующий код:

def j(l): 
    p = [] 
    for i in l: 
     digcode = i.split('.')[0] 
     if any(s.startswith(digcode[:2]) for s in p): #there exists prefex in list 
      if digcode[2:] > p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]: 
       p.pop([n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]) 
       p.append(digcode) 
      else: 
       pass 
     else: 
      p.append(digcode) 
    return p 

Но когда я применяю его к более крупный образец не выполняет точной работы

>>> o = ['AS6.json', 'AS7.json', 'AS8.json', 'AS9.json', 'BS1.json', 'BS2.json', 'BS3.json', 'BS4.json', 'BS5.json', 'CS1.json', 'CS2.json', 'CS3.json', 'CS4.json', 'CS5.json', 'CS6.json', 'DS10.json', 'DS11.json', 'DS4.json', 'DS5.json', 'DS6.json', 'DS7.json', 'DS8.json', 'DS9.json', 'ES4.json', 'ES5.json', 'ES6.json', 'FS5.json', 'FS6.json', 'FS7.json', 'FS8.json', 'MS4.json', 'MS5.json', 'MS6.json', 'MS7.json', 'MS8.json', 'MS9.json', 'NR1.json', 'NR2.json', 'NR3.json', 'NR4.json', 'NR5.json', 'NR6.json', 'NR7.json', 'NR8.json', 'VR1.json', 'VR2.json', 'VR3.json', 'VR4.json', 'VR5.json', 'VR6.json', 'VR7.json', 'VR8.json', 'XS11.json', 'XS9.json'] 

>>> j(o) 
['AS9', 'BS5', 'CS6', 'DS9', 'ES6', 'FS8', 'MS9', 'NR8', 'VR8', 'XS9'] 

, что неверно, поскольку в качестве примера приведены XS11 и DS11.

Буду признателен, если кто-то поможет мне исправить мою проблему или, возможно, найти более простое решение моей проблемы. Спасибо

+0

Вы пробовали без списка понимания, который по общему признанию было бы легче получить право? –

ответ

2

Вы делаете string сравнение; '9' больше '11', потому что символ '9' наступает позже в алфавите. Сначала вам придется преобразовать их в целые числа.

Я хотел бы использовать словарь для отображения префиксов до максимального числа:

def find_latest(lst): 
    prefixes = {} 
    for entry in lst: 
     code, value = entry[:2], int(entry.partition('.')[0][2:]) 
     if value > prefixes.get(code, (float('-inf'), ''))[0]: 
      prefixes[code] = (value, entry) 
    return [entry for value, entry in prefixes.values()] 

Это является гораздо более эффективным, поскольку это не цикл по всему списку ввода каждый раз; вы обрабатываете список N^2 раза (добавьте один элемент, и вы добавляете N тестов для работы); он обрабатывает ваш список в N шагах. Поэтому вместо 100 тестов для 10 элементов это просто выполняет 10 тестов.

Демо:

>>> sample = ['AS6.json', 'AS7.json', 'AS8.json', 'AS9.json', 'BS1.json', 'BS2.json', 'BS3.json', 'BS4.json', 'BS5.json', 'CS1.json', 'CS2.json', 'CS3.json', 'CS4.json', 'CS5.json', 'CS6.json', 'DS10.json', 'DS11.json', 'DS4.json', 'DS5.json', 'DS6.json', 'DS7.json', 'DS8.json', 'DS9.json', 'ES4.json', 'ES5.json', 'ES6.json', 'FS5.json', 'FS6.json', 'FS7.json', 'FS8.json', 'MS4.json', 'MS5.json', 'MS6.json', 'MS7.json', 'MS8.json', 'MS9.json', 'NR1.json', 'NR2.json', 'NR3.json', 'NR4.json', 'NR5.json', 'NR6.json', 'NR7.json', 'NR8.json', 'VR1.json', 'VR2.json', 'VR3.json', 'VR4.json', 'VR5.json', 'VR6.json', 'VR7.json', 'VR8.json', 'XS11.json', 'XS9.json'] 
>>> def find_latest(lst): 
...  prefixes = {} 
...  for entry in lst: 
...   code, value = entry[:2], int(entry.partition('.')[0][2:]) 
...   if value > prefixes.get(code, (float('-inf'), ''))[0]: 
...    prefixes[code] = (value, entry) 
...  return [entry for value, entry in prefixes.values()] 
... 
>>> find_latest(sample) 
['FS8.json', 'VR8.json', 'AS9.json', 'MS9.json', 'BS5.json', 'CS6.json', 'XS11.json', 'NR8.json', 'DS11.json', 'ES6.json'] 
+0

Спасибо, отличный ответ :) Не могли бы вы указать мне в правильном направлении в отношении выполнения этого рекурсивно? – user3374113

+0

@ user3374113: трудно дать вам указания без подсказки относительно того, как будет выглядеть структура, что потребует рекурсии. –

1

Это выглядит так, как будто ваши digcode[2:] значения сравниваются лексикографически (словарную заказ), а не численно.

Таким образом, 9 считается «больше чем» 11, потому что в списке слов слово, начинающееся с «9», должно появиться после слова, начинающегося с «11».

Для сравнения следует преобразовать digcode[2:] в ряд т.е. int(digcode[2:])

if digcode[2:] > p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]: 

в

if int(digcode[2:]) > int(p[[n for n, l in enumerate(p) if l.startswith(digcode[:2])][0]][2:]): 

Это дает:

>>> j(o) 
['AS9', 'BS5', 'CS6', 'DS11', 'ES6', 'FS8', 'MS9', 'NR8', 'VR8', 'XS11'] 
Смежные вопросы