2015-10-28 8 views
2

у меня есть большой список слов:Python - Количество элементов списка в пределах диапазона заданных значений

my_list = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 

Я хотел бы иметь возможность подсчитать количество элементов между (и включая) [tag] во всем списке. Цель состоит в том, чтобы видеть распределение частоты.

Могу ли я использовать range() для запуска и остановки по совпадению строк?

+0

>>> из коллекции импорта Счетчик >>> г = [ 'синий', 'красный', 'синий', 'желтый', «синий ',' red '] >>> Счетчик (z) Счетчик ({' blue ': 3,' red ': 2,' yellow ': 1}) –

+0

@ami, который не учитывает элементы между двумя значениями. Это подсчет количества раз, когда элемент отображается во всем списке. – Andy

+0

Я рассчитываю рассчитать общее количество элементов между [тегом] и [/ тегом] (включительно), а не только, сколько раз одна строка отображается в списке. – user3939059

ответ

0

Решение с использованием списка понимания и манипуляций со строками.

my_list = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 

# string together your list 
my_str = ','.join(mylist) 

# split the giant string by tag, gives you a list of comma-separated strings 
my_tags = my_str.split('[tag]') 

# split for each word in each tag string 
my_words = [w.split(',') for w in my_tags] 

# count up each list to get a list of counts for each tag, adding one since the first split removed [tag] 
my_cnt = [1+len(w) for w in my_words] 

ли это одна строка:

# all as one list comprehension starting with just the string 
[1+len(t.split(',')) for t in my_str.split('[tag]')] 
0

Я бы пошел со следующим, поскольку OP хочет подсчитать фактические значения. (Нет сомнений в том, что он понял, как сделать это сейчас.)

i = [k for k, i in enumerate(my_list) if i == '[tag]'] 
j = [k for k, p in enumerate(my_list) if p == '[/tag]'] 
for z in zip(i,j): 
    print (z[1]-z[0]) 
1

Вы можете использовать .index(value, [start, [stop]]) для поиска по списку.

my_list = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 
my_list.index('[tag']) # will return 0, as it occurs at the zero-eth element 
my_list.index('[/tag]') # will return 6 

Это поможет вам вашу первую длину группы, а затем на следующей итерации вам просто нужно помнить, что индекс последнего закрывающего тега был, и использовать его в качестве начальной точки, плюс 1

my_list.index('[tag]', 7)  # will return 7 
my_list.index(['[/tag]'), 7) # will return 11 

И сделайте это в цикле, пока не достигнете своего последнего закрывающего тега в своем списке. Также помните, что .index поднимет значение ValueError, если это значение отсутствует, поэтому вам нужно обработать это исключение, когда оно произойдет.

5

Прежде всего, найдите все индексы [tag], разница между соседними индексами - это количество слов.

my_list = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 
indices = [i for i, x in enumerate(my_list) if x == "[tag]"] 
nums = [] 
for i in range(1,len(indices)): 
    nums.append(indices[i] - indices[i-1]) 

Более быстрый способ найти все индексы использует NumPy, как показано ниже:

import numpy as np 
values = np.array(my_list) 
searchval = '[tag]' 
ii = np.where(values == searchval)[0] 
print ii 

Другой способ получить разность между соседними индексами использует itertools,

import itertools 
diffs = [y-x for x, y in itertools.izip (indices, indices[1:])] 
0

Это должно позволяют находить количество слов между вашими тегами:

MY_LIST = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 
      'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 


def main(): 
    ranges = find_ranges(MY_LIST, '[tag]', '[/tag]') 
    for index, pair in enumerate(ranges, 1): 
     print('Range {}: Start = {}, Stop = {}'.format(index, *pair)) 
     start, stop = pair 
     print('   Size of Range =', stop - start + 1) 


def find_ranges(iterable, start, stop): 
    range_start = None 
    for index, value in enumerate(iterable): 
     if value == start: 
      if range_start is None: 
       range_start = index 
      else: 
       raise ValueError('a start was duplicated before a stop') 
     elif value == stop: 
      if range_start is None: 
       raise ValueError('a stop was seen before a start') 
      else: 
       yield range_start, index 
       range_start = None 

if __name__ == '__main__': 
    main() 

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

Range 1: Start = 0, Stop = 6 
     Size of Range = 7 
Range 2: Start = 7, Stop = 11 
     Size of Range = 5 
Range 3: Start = 12, Stop = 15 
     Size of Range = 4 
0

Заимствования и слегка модифицировать код генератора от выбранного ответа на this question:

my_list = ['[tag]', 'there', 'are', 'many', 'words', 'here', '[/tag]', '[tag]', 'some', 'more', 'here', '[/tag]', '[tag]', 'and', 'more', '[/tag]'] 

def group(seq, sep): 
    g = [] 
    for el in seq: 
     g.append(el) 
     if el == sep: 
      yield g 
      g = [] 

counts = [len(x) for x in group(my_list,'[/tag]')] 

Я изменил генератор, который они дали в этом ответе, чтобы не возвращать пустой список в конце и включать разделитель в список вместо того, чтобы помещать его в следующий список. Обратите внимание, что это предполагает, что в этом порядке всегда будет пара совпадений [tag] '' [/ tag] в этом порядке и что все элементы в списке находятся между парой.

После выполнения этой команды на счету будет [7,5,4]

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