2017-02-15 4 views
3

В следующем коде я хочу подсчитать количество слов в word_list в test, код ниже может выполнить эту работу, но может быть неэффективен, есть ли лучший способ сделай это?Элемент списка экземпляров Python list1 в списке2

word_list = ["hello", "wonderful", "good", "flawless", "perfect"] 
test = ["abc", "hello", "vbf", "good", "dfdfdf", "good", "good"] 

result = [0] * len(word_list) 
for i in range(len(word_list)): 
    for w in test: 
     if w == word_list[i]: 
      result[i] += 1 

print(result) 

ответ

6

Использование collections.Counter сосчитать все слова в test на одном дыхании, то просто получить, что отсчет от Counter для каждого слова в word_list.

>>> word_list = ["hello", "wonderful", "good", "flawless", "perfect"] 
>>> test = ["abc", "hello", "vbf", "good", "dfdfdf", "good", "good"] 
>>> counts = collections.Counter(test) 
>>> [counts[w] for w in word_list] 
[1, 0, 3, 0, 0] 

Или с помощью словаря comprehention:

>>> {w: counts[w] for w in word_list} 
{'perfect': 0, 'flawless': 0, 'good': 3, 'wonderful': 0, 'hello': 1} 

Создание счетчика должно быть O (п), и каждый поиск O (1), давая вам O (N + M) для русских слов в test и m слов в word_list.

+0

не было бы более эффективно делать фильтрацию в первую очередь? Кроме того, ссылаясь на эту страницу: https://wiki.python.org/moin/TimeComplexity, поиск в списке - O (n), это может быть улучшено до O (1), если вы конвертируете 'word_list' в задавать. –

+0

@ZaccharieRamzi Что со всем, что «делает поиск в наборе» сегодня? Ты второй, кто предложил это. Является ли мой ответ неясным? Я не делаю поиск в списке, только здесь, в dict, который так же быстро, как и поиск в наборе. Кроме того, какая фильтрация? –

+0

Да, вы правы, я смутился тем, что имел в виду. Если вы это сделаете: 'words = set (word_list); new_test = [слово в слово в тесте, если слово в словах]; counts = collections.Counter (new_test) ' , у вас могут быть более быстрые результаты в зависимости от ситуации. –

3

Вы можете сделать это в линейном режиме, используя словарь.

word_list = ["hello", "wonderful", "good", "flawless", "perfect"] 
test = ["abc", "hello", "vbf", "good", "dfdfdf", "good", "good"] 

result = [] 
word_map = {} 
for w in test: 
    if w in word_map: 
     word_map[w] += 1 
    else: 
     word_map[w] = 1 

for w in word_list: 
    result.append(word_map.get(w, 0)) 

print(result) 
+2

Nice решение «нет библиотеки», но даже тогда вы можете сделать этот код немного более компактный, используя 'get' с дефолтом, например, 'result.append (word_map.get (w, 0))' –

1

Вы можете комбинировать collections.Counter и operator.itemgetter:

from collections import Counter 
from operator import itemgetter 

cnts = Counter(test) 
word_cnts = dict(zip(word_list, itemgetter(*word_list)(cnts))) 

Что дает:

>>> word_cnts 
{'flawless': 0, 'good': 3, 'hello': 1, 'perfect': 0, 'wonderful': 0} 

или, если вы предпочитаете хотите как list:

>>> list(zip(word_list, itemgetter(*word_list)(cnts))) 
[('hello', 1), ('wonderful', 0), ('good', 3), ('flawless', 0), ('perfect', 0)] 
+0

Впечатляющий показ функционального программирования, но я все же предпочел бы, чтобы список или понимание понятий. ;-) –

+0

@tobias_k Понятия уже были «приняты» другим ответом. В противном случае я бы добавил их: -P – MSeifert

-1

Вы можете попробовать использовать dictionnaries:

word_list = ["hello", "wonderful", "good", "flawless", "perfect"] 
test = ["abc", "hello", "vbf", "good", "dfdfdf", "good", "good"] 

result = {} 
for word in word_list: 
    result[word]=0 
for w in test: 
    if result.has_key(w): 
     result[w] += 1 
print(result) 

Но вы бы закончили с другой структурой. Если вы не хотите, что вы могли бы попробовать это вместо

word_list = ["hello", "wonderful", "good", "flawless", "perfect"] 
test = ["abc", "hello", "vbf", "good", "dfdfdf", "good", "good"] 

result = {} 
for w in test: 
    if(result.has_key(w)): 
     result[w] += 1 
    else: 
     result[w] = 1 
count = [0] * len(word_list) 
for i in range(len(word_list)): 
    if (result.has_key(word_list[i])): 
     count[i]=result[word_list[i]] 
print(count)