С 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
. 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]
Ну, этот мог бы быть быстрее, поскольку он сравнивает в C:
def occurrences(string, sub):
count = start = 0
while True:
start = string.find(sub, start) + 1
if start > 0:
count+=1
else:
return count
Это еще один пример использования 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
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
Выше кода просто повторяется по всей строке один раз и продолжает проверять, начинается ли какая-либо строка с конкретной подсчитанной подстрокой.
def count_substring(string, sub_string):
count=0
for pos in range(len(string)):
if string[pos:].startswith(sub_string):
count+=1
return count
Это может быть самым простым способом.
Для дублированного вопроса я решил посчитать его 3 на 3 и сравнить строку, например.
counted = 0
for i in range(len(string)):
if string[i*3:(i+1)*3] == 'xox':
counted = counted +1
print counted
Вот мое решение 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)
Вы также можете попробовать использовать новый модуль регулярного выражения 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
Если строки велики, вы хотите использовать Rabin-Karp , в итоге:
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')
Функция, которая принимает в качестве входных данных две строки и подсчитывает, сколько раз субподходит в строке, включая перекрытия. Чтобы проверить, является ли 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
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 в списке даст нам общее количество найденных совпадений.
Это можно решить с помощью регулярного выражения.
import re
def function(string, sub_string):
match = re.findall('(?='+sub_string+')',string)
return len(match)
Если вы хотите подсчитать количество перестановок длины 5 (отрегулируйте, если хотите для разных длин):
def MerCount(s):
for i in xrange(len(s)-4):
d[s[i:i+5]] += 1
return d
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
Эта функция (другое решение!) получает шаблон и текст. Возвращает список со всей подстрокой, расположенной в их и их положениях.
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)]
blockquote>
Мой ответ на вопрос 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
s = "bobobob"
sub = "bob"
ln = len(sub)
print(sum(sub == s[i:i+ln] for i in xrange(len(s)-(ln-1))))
Альтернатива, очень близкая к принятому ответу, но использующая 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:
и является немного чище по-моему
count= start= 0
. Нет реальной причины для распаковки кортежей здесь. – tzot 4 June 2010 в 01:15