【问题标题】:Python - Count elements of a list within a range of specified valuesPython - 在指定值范围内计算列表的元素
【发布时间】:2016-01-28 06:41:47
【问题描述】:

我有很多单词:

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

我希望能够计算整个列表中 [tag] 元素之间(包括)之间的元素数量。目标是能够看到频率分布。

我可以使用range() 来启动和停止字符串匹配吗?

【问题讨论】:

  • >>> from collections import Counter >>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red'] >>> Counter( z) 计数器({'blue': 3, 'red': 2, 'yellow': 1})
  • @ami,这不计算两个值之间的元素。那就是计算一个元素在整个列表中出现的次数。
  • 我希望计算 [tag] 和 [/tag](含)之间的项目总数,而不是一个字符串在列表中出现的次数。
  • 您的示例不包括任何不会被计算在内的条目。
  • range 是一个内置函数,它返回一个数字列表。如果您已经知道所有标签的列表索引,那么您可以使用 range 来生成标签内的列表项的索引。但是你就不需要它们了,因为你已经知道了这个问题所需的一切,而无需查看列表。

标签: python


【解决方案1】:

我会选择以下内容,因为 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])

【讨论】:

    【解决方案2】:

    您可以使用.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,因此当它发生时您需要处理该异常。

    【讨论】:

      【解决方案3】:

      首先,找到[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:])]
      

      【讨论】:

        【解决方案4】:

        这应该可以让您找到标签之间和包含标签的单词数:

        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
        

        【讨论】:

          【解决方案5】:

          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]

          【讨论】:

            【解决方案6】:

            使用列表理解和字符串操作的解决方案。

            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]')]
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-01-22
              • 1970-01-01
              • 2023-02-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-04-03
              相关资源
              最近更新 更多