2015-08-30 3 views
-1

У меня есть список из примерно 1 300 000 предметов. Например, ['.a', '.b.a', '.c.b', '.f.c.b'].Python 2.7: Удалить субдомены из списка

Я хотел бы удалить субдомены (например, «.b.a» и «.f.c.b» в приведенном выше списке).

Я новичок. Я пытаюсь узнать о скорости. Ниже приведены мои попытки, которые кажутся медленными. Любые предложения:

# create separate lists, perhaps that is faster 
a1 = [] 
b2 = [] 
c3 = [] 
d4 = [] 
e5 = [] 
f6 = [] 
for i in dupesgone: 
    j = i.count('.') 
    if j == 1: 
     a1.append(i) 
    elif j == 2: 
     b2.append(i) 
    elif j == 3: 
     c3.append(i) 
    elif j == 4: 
     d4.append(i) 
    elif j == 5: 
     e5.append(i) 
    else: 
     f6.append(i) 

for a in a1: 
    la = -len(a) 
    for b in b2: 
     if a == b[la:]: 
      b2.remove(b) 
    for c in c3: 
     if a == c[la:]: 
      c3.remove(c) 
    for d in d4: 
     if a == d[la:]: 
      d4.remove(d) 
    --snip-- 

# how about this, is this faster 
[b2.remove(b) for b in b2 for a in a1 if a == b[-len(a):]] 
[c3.remove(c) for c in c3 for a in a1 if a == c[-len(a):]] 
[d4.remove(d) for d in d4 for a in a1 if a == d[-len(a):]] 
[e5.remove(e) for e in e5 for a in a1 if a == e[-len(a):]] 
[f6.remove(f) for f in f6 for a in a1 if a == f[-len(a):]] 

Должен ли я создать словарь? Будет ли это быстрее?

Благодарим за помощь.

+0

насчет '.c.b'? – styvane

+3

'a == b [-len (a):]' может быть более четко выражено как 'b.endswith (a)', вы не должны использовать методы списка для побочных эффектов, и вам следует попытаться уменьшить дублирование. Если это ** рабочий код **, который, по вашему мнению, может быть улучшен, рассмотрите http://codereview.stackexchange.com – jonrsharpe

+0

Вместо того, чтобы спрашивать, какой из двух фрагментов кода, который вы написали, быстрее ... почему бы вы сами их измеряете? – thebjorn

ответ

1

С практической точки зрения, я думаю, самый быстрый алгоритм будет

  1. Обратно каждый элемент (так что «.bc» становится «cb»)
  2. Сортировка списка
  3. Прокрутите список с идеей «текущего» элемента. Если следующий элемент в списке начинается с (т. Е. Является субдоменом) текущего элемента, следующий элемент добавляется в список вывода и становится текущим.
  4. Reverse каждый элемент в списке вывода

Вот непроверенный эскиз кода:

def reverse(s): 
    return s[::-1] 

r = map(reverse, devgone) 
r.sort() 
ci = None 
out = [] 
for ni in r: 
    if not ci or not ni.startswith(ci): 
    out.append(ni) 
    ci = ni 
return map(reverse, out) 
+0

Это ужасно быстро! Благодарю вас! –

2

Это часто быстрее просто создать новый список, чем удалить элементы, которые не соответствуют:

dupesgone = [domain for domain in dupesgone if domain.count(".") == 1] 
+0

Несмотря на фильтрацию, основанную на 'len (domain) == 2, этот подход также будет заботиться о таких доменах, как' .abc' или '.abc.def', поскольку он подсчитывает вхождения' .'. – albert

+0

Это добавило моих навыков, спасибо. –

Смежные вопросы