Подсчитайте количество раз, когда вспомогательная строка встречается в строке в Python [duplicate]

С new_list = my_list у вас фактически нет двух списков. Назначение просто копирует ссылку на список, а не фактический список, поэтому оба new_list и my_list относятся к тому же списку после назначения.

Чтобы на самом деле скопировать список, у вас есть различные возможности :

  • Вы можете использовать встроенный метод list.copy() (доступный с python 3.3):
    new_list = old_list.copy()
    
  • Вы можете отрезать его:
    new_list = old_list[:]
    
    мнение Алексея Мартелли (по крайней мере, в 2007 году ) об этом означает, что это странный синтаксис, и нет смысла использовать его когда-либо . ;) (По его мнению, следующий более читабель).
  • Вы можете использовать встроенную функцию list() :
    new_list = list(old_list)
    
  • Вы можете использовать общий copy.copy() :
    import copy
    new_list = copy.copy(old_list)
    
    Это немного медленнее, чем list(), потому что сначала он должен узнать тип данных old_list.
  • Если список содержит объекты, и вы также хотите их скопировать, используйте generic copy.deepcopy() :
    import copy
    new_list = copy.deepcopy(old_list)
    
    Очевидно, самый медленный и самый необходимый для памяти способ, но иногда неизбежный.

Пример:

import copy

class Foo(object):
    def __init__(self, val):
         self.val = val

    def __repr__(self):
        return str(self.val)

foo = Foo(1)

a = ['foo', foo]
b = a.copy()
c = a[:]
d = list(a)
e = copy.copy(a)
f = copy.deepcopy(a)

# edit orignal list and instance 
a.append('baz')
foo.val = 5

print('original: %r\n list.copy(): %r\n slice: %r\n list(): %r\n copy: %r\n deepcopy: %r'
      % (a, b, c, d, e, f))

Результат:

original: ['foo', 5, 'baz']
list.copy(): ['foo', 5]
slice: ['foo', 5]
list(): ['foo', 5]
copy: ['foo', 5]
deepcopy: ['foo', 1]

44
задан Kevin 11 August 2014 в 16:21
поделиться

20 ответов

Ну, этот мог бы быть быстрее, поскольку он сравнивает в C:

def occurrences(string, sub):
    count = start = 0
    while True:
        start = string.find(sub, start) + 1
        if start > 0:
            count+=1
        else:
            return count
59
ответ дан Jochen Ritzel 21 August 2018 в 00:39
поделиться
  • 1
    Определенно +1. Хотя я бы предпочел count= start= 0. Нет реальной причины для распаковки кортежей здесь. – tzot 4 June 2010 в 01:15
  • 2
    @ ΤΖΩΤΖΙΟΥ: Черт, я не знал, что вы можете это сделать. Точнее, я, должно быть, забыл, так как я уверен, что прошел весь учебник, когда впервые учился (и да, я подтвердил это в учебнике). Но я никогда не вижу, чтобы кто-то использовал прикованное задание; тогда как я вижу назначение кортежа все время. Идти рис. – John Y 4 June 2010 в 04:05
  • 3
    Очень полезно, это вдохновило небольшую часть перекрывающегося количества строк, которое я реализовал в BioPython, сообщите мне, если вы хотите добавить какую-то атрибуцию github.com/biopython/biopython/blob/master/Bio/Seq. ру # L486 – Chris_Rands 16 October 2017 в 20:36

Это еще один пример использования str.find(), но многие ответы делают его более сложным, чем необходимо:

def occurrences(text, sub):
    c, n = 0, text.find(sub)
    while n != -1:
        c += 1
        n = text.find(sub, n+1)
    return c

In []:
occurrences('1011101111', '11')

Out[]:
5
0
ответ дан AChampion 21 August 2018 в 00:39
поделиться
def count_substring(string, sub_string):
    counter = 0
    for i in range(len(string)):
        if string[i:].startswith(sub_string):
        counter = counter + 1
    return counter

Выше кода просто повторяется по всей строке один раз и продолжает проверять, начинается ли какая-либо строка с конкретной подсчитанной подстрокой.

1
ответ дан Anshul Tiwari 21 August 2018 в 00:39
поделиться
  • 1
    Кодовые ответы не рекомендуется, потому что они не объясняют, как они решают проблему. Пожалуйста, обновите свой ответ, чтобы объяснить, как это улучшается на других принятых и поддержанных ответах, которые уже заданы этим вопросом. Кроме того, этот вопрос составляет 7 лет, ваши усилия будут более оценены пользователями, у которых есть недавние неотвеченные вопросы. Пожалуйста, просмотрите Как написать хороший ответ . – FluffyKitten 20 September 2017 в 00:10
  • 2
    Выше кода просто повторяется по всей строке один раз и продолжает проверять, начинается ли какая-либо строка с конкретной подсчитанной подстрокой. – Anshul Tiwari 20 September 2017 в 13:46
  • 3
    Вы должны отредактировать свой ответ , чтобы добавить эту информацию, поскольку ее можно пропустить в комментариях. – FluffyKitten 20 September 2017 в 18:55
def count_substring(string, sub_string):
count=0
for pos in range(len(string)):
    if string[pos:].startswith(sub_string):
        count+=1
return count

Это может быть самым простым способом.

1
ответ дан Arun Tom 21 August 2018 в 00:39
поделиться

Для дублированного вопроса я решил посчитать его 3 на 3 и сравнить строку, например.

counted = 0

for i in range(len(string)):

    if string[i*3:(i+1)*3] == 'xox':
       counted = counted +1

print counted
6
ответ дан Community 21 August 2018 в 00:39
поделиться

Вот мое решение edx MIT «find bob» * (* найти количество вхождений «bob» в строке с именем s), которая в основном подсчитывает перекрывающиеся вхождения данной подстанции:

s = 'azcbobobegghakl'
count = 0

while 'bob' in s:
    count += 1 
    s = s[(s.find('bob') + 2):]

print "Number of times bob occurs is: {}".format(count)
1
ответ дан dasdachs 21 August 2018 в 00:39
поделиться

Вы также можете попробовать использовать новый модуль регулярного выражения Python , который поддерживает совпадающие совпадения.

import regex as re

def count_overlapping(text, search_for):
    return len(re.findall(search_for, text, overlapped=True))

count_overlapping('1011101111','11')  # 5
9
ответ дан David C 21 August 2018 в 00:39
поделиться

Если строки велики, вы хотите использовать Rabin-Karp , в итоге:

  • развертки окна размера подстроки, перемещение по строке
  • хэш с O (1) служебными данными для добавления и удаления (т. е. перемещение на 1 символ)
  • , реализованного в C или полагающегося на pypy
0
ответ дан Dima Tisnek 21 August 2018 в 00:39
поделиться
def count_overlaps (string, look_for):
    start   = 0
    matches = 0

    while True:
        start = string.find (look_for, start)
        if start < 0:
            break

        start   += 1
        matches += 1

    return matches

print count_overlaps ('abrabra', 'abra')
0
ответ дан doublep 21 August 2018 в 00:39
поделиться

Функция, которая принимает в качестве входных данных две строки и подсчитывает, сколько раз субподходит в строке, включая перекрытия. Чтобы проверить, является ли sub подстрокой, я использовал оператор in.

def count_Occurrences(string, sub):
    count=0
    for i in range(0, len(string)-len(sub)+1):
        if sub in string[i:i+len(sub)]:
            count=count+1
    print 'Number of times sub occurs in string (including overlaps): ', count
0
ответ дан Fidiana 21 August 2018 в 00:39
поделиться

sum([ 1 for _ in range(len(string)-len(str_to_search_for)+1) if string[_:_+len(str_to_search_for)] == str_to_search_for])

В понимании списка мы перемещаем большую строку по одной позиции за раз с скользящим окном длины меньшей строки. Мы можем вычислить скользящее число, вычитая длину меньшей строки из большей строки. Для каждого слайда мы сравниваем ту часть большей строки с нашей меньшей строкой и генерируем 1 в списке, если совпадение найдено. Сумма всех этих 1 в списке даст нам общее количество найденных совпадений.

-1
ответ дан Hicham Mounadi 21 August 2018 в 00:39
поделиться

Это можно решить с помощью регулярного выражения.

import re
def function(string, sub_string):
    match = re.findall('(?='+sub_string+')',string)
    return len(match)
1
ответ дан Himanshu Bhagwani 21 August 2018 в 00:39
поделиться

Если вы хотите подсчитать количество перестановок длины 5 (отрегулируйте, если хотите для разных длин):

def MerCount(s):
  for i in xrange(len(s)-4):
    d[s[i:i+5]] += 1
return d
-1
ответ дан hims056 21 August 2018 в 00:39
поделиться
  • 1
    «подсчет перестановок подсчета» для меня не имеет большого значения. d не является определенным именем. Если код действительно выполнялся, он не ответил бы на вопрос. – Terry Jan Reedy 7 March 2015 в 21:43
>>> import re
>>> text = '1011101111'
>>> len(re.findall('(?=11)', text))
5

Если вы не хотите загружать весь список совпадений в память, это никогда не будет проблемой! вы можете сделать это, если хотите:

>>> sum(1 for _ in re.finditer('(?=11)', text))
5

Как функция (re.escape, убедитесь, что подстрока не мешает регулярному выражению):

>>> def occurrences(text, sub):
        return len(re.findall('(?={0})'.format(re.escape(sub)), text))

>>> occurrences(text, '11')
5
34
ответ дан jamylak 21 August 2018 в 00:39
поделиться

Как найти шаблон в другой строке с перекрытием

Эта функция (другое решение!) получает шаблон и текст. Возвращает список со всей подстрокой, расположенной в их и их положениях.

def occurrences(pattern, text):
    """
    input: search a pattern (regular expression) in a text
    returns: a list of substrings and their positions 
    """
    p = re.compile('(?=({0}))'.format(pattern))
    matches = re.finditer(p, text)
    return [(match.group(1), match.start()) for match in matches]

print (occurrences('ana', 'banana'))
print (occurrences('.ana', 'Banana-fana fo-fana'))

[('ana', 1), ('ana', 3)] [('Bana', 0), ('nana', 2), ('fana', 7), ('fana', 15)]

2
ответ дан Jose Raul Barreras 21 August 2018 в 00:39
поделиться

Мой ответ на вопрос bob о курсе:

s = 'azcbobobegghaklbob'
total = 0
for i in range(len(s)-2):
    if s[i:i+3] == 'bob':
        total += 1
print 'number of times bob occurs is: ', total
2
ответ дан Luke D 21 August 2018 в 00:39
поделиться
s = "bobobob"
sub = "bob"
ln = len(sub)
print(sum(sub == s[i:i+ln] for i in xrange(len(s)-(ln-1))))
3
ответ дан Padraic Cunningham 21 August 2018 в 00:39
поделиться

Альтернатива, очень близкая к принятому ответу, но использующая while в качестве теста if вместо включения if внутри цикла:

def countSubstr(string, sub):
    count = 0
    while sub in string:
        count += 1
        string = string[string.find(sub) + 1:]
    return count;

Это позволяет избежать while True: и является немного чище по-моему

0
ответ дан stevoblevo 21 August 2018 в 00:39
поделиться
6
ответ дан Community 31 October 2018 в 19:36
поделиться
0
ответ дан pylang 31 October 2018 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: