from urllib.parse import urlparse
from bs4 import BeautifulSoup
import requests
import lxml
DOMAIN = 'apexair.ru'
HOST = 'http://' + DOMAIN
FORBIDDEN_PREFIXES = ['#', 'tel:', 'mailto:']
links = set() # множество всех ссылок
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
response = requests.get(HOST, headers=headers)
# print(response.content)
def add_all_links_recursive(url, maxdepth=1):
# print('{:>5}'.format(len(links)), url[len(HOST):])
# глубина рекурсии не более `maxdepth`
# список ссылок, от которых в конце мы рекурсивно запустимся
links_to_handle_recursive = []
# получаем html код страницы
request = requests.get(url, headers=headers)
# парсим его с помощью BeautifulSoup
soup = BeautifulSoup(request.content, 'lxml')
# рассматриваем все теги <a>
for tag_a in soup.find_all('a', href=lambda v: v is not None):
link = tag_a['href']
# если ссылка не начинается с одного из запрещённых префиксов
if all(not link.startswith(prefix) for prefix in FORBIDDEN_PREFIXES):
# проверяем, является ли ссылка относительной
# например, `/oplata` --- это относительная ссылка
# `http://101-rosa.ru/oplata` --- это абсолютная ссылка
if link.startswith('/') and not link.startswith('//'):
# преобразуем относительную ссылку в абсолютную
link = HOST + link
# проверяем, что ссылка ведёт на нужный домен
# и что мы ещё не обрабатывали такую ссылку
if urlparse(link).netloc == DOMAIN and link not in links:
links.add(link)
links_to_handle_recursive.append(link)
if maxdepth > 0:
for link in links_to_handle_recursive:
add_all_links_recursive(link, maxdepth=maxdepth - 1)
def main():
add_all_links_recursive(HOST + '/')
for link in links:
print(link)
if __name__ == '__main__':
main()
data=[
['дата', '1', '2', '3', '4', '5', '6', '7', ...],
['Ноябрь 2019', '11', '22', '33', '44', '55', '66', '77', ...],
['Декабрь 2019', '11', '22', '33', '44', '55', '66', '77', ...],
...
]
import datetime
import locale
def replace_month(dt: str) -> str:
dt = dt.replace('Январь', 'января')
dt = dt.replace('Февраль', 'февраля')
# ...
return dt
locale.setlocale(locale.LC_TIME, "ru_RU.utf8")
head = data[0]
data = data[1:]
result_rows = []
for row in data:
for day, value in zip(head[1:], row[1:]):
dt = replace_month(f'{day} {row[0]}')
try:
dt = datetime.datetime.strptime(dt, '%d %B %Y')
except ValueError:
pass # тут у нас дата не сконвертнулась, например, 30 февраля. Пофиг.
else:
result_rows.append((dt, value))
module = importlib.import_module('my_module_name')
classes = [
value
for value in (
getattr(module, name)
for name in dir(module)
)
if isinstance(value, type)
and getattr(value, '__module__', None) == module.__name__
]
data['custom_answer']
равно тому, что вы привели в качестве примера (хотя закрывающую фигурную скобку забыли), то код сработает верно и без ошибок."string indices must be integers"
In [1]: 'qwerty'['xxx']
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-6-994fc1ca7c86> in <module>
----> 1 'qwerty'['xxx']
TypeError: string indices must be integers
Вот такой массив передаю в 'custom_answer'
Теперь мне нужно результат получить и "забрать".
def task_v1():
"""
Принимает на вход строки (признак конца ввода - пустая строка),
сохраняет их в список без повторений.
Печатает сохранённые в списке строки.
"""
lst = [] # делаем пустой список
s = input() # вводим первую строку
while s: # пока введённая строка не пуста:
if s not in lst: # если строка не в списке:
lst.append(s) # добавляем её
s = input() # принимаем следующую строку
print('\n'.join(lst)) # объединяем все строки через абзац и печатаем
def task_v2():
"""
Также принимает на вход строки, но сохраняет их в Счётчик.
Счётчик и порядок добавления запоминает и считает количество повторов.
Печатает ключи счётчика.
"""
from collections import Counter # импортируем класс счётчика
c = Counter() # создаём экземпляр Счётчика
s = input() # вводим первую строку
while s: # пока введённая строка не пуста:
c[s] += 1 # подсчитываем её счётчиком
s = input() # принимаем следующую строку
print('\n'.join(c)) # объединяем ключи счётчика через абзац и печатаем
def task_v3():
"""
То же, что и v2, но в функциональном стиле
"""
from collections import Counter # импортируем класс счётчика
print( # функция печати, которой даём строку...
'\n'.join( # которую формируем объединяя через абзац элементы (строки) полученные...
Counter( # созданием экземпляра счётчика, которому в конструктор передаём...
iter(input, '') # итератор, который будет вызывать функцию input пока она не вернёт '',
# а результаты всех вызовов (кроме последнего) будет возвращать по мере
# запроса их конструктором Счётчика (для подсчёта)
).keys() # и формированием списка уникальных ключей (строк) из счётчика.
# ктсати `.keys()` совершенно не нужен. Итаратор по счётчику возвращает ключи.
)
)
def task_v3_1():
"""В одну строку это выглядит не так ужасно:"""
print('\n'.join(Counter(iter(input, ''))))
def task_v4():
"""
То же, что и v3, но расписано на этапы и сохранено в промежуточные переменные
"""
from collections import Counter # импортируем класс счётчика
it = iter(input, '') # создаём итератор, который по мере запроса у него
# очередных значений будет вызывать функцию
# input пока она не вернёт пустую строку
c = Counter(it) # создаём экземпляр Счётчика и в качестве аргумента
# даём ему наш итератор. тем самым мы предлагаем
# нашему новому счётчику запросить все значения,
# что отдаст итератор и посчитать количество
# вхождений каждой уникальной строки
unic = c.keys() # получаем у счётчика его ключи, то есть все
# уникальные строки, которые он считал.
# Приятный побочный эффект, доступный в современном
# Питоне - это сохранение порядка ключей по мере ввода.
# Этот шаг не обязателен, поскольку счётчик итерируется по ключам.
result_text = '\n'.join(unic) # объединяем все уникальные строки через абзац. Вместо unic можно просто указать `c`.
print(result_text) # и печатаем их
$ py "set(iter(input,''))"
$ cat<<""|py -l "set(l)"
$ cat<<""|py -l "collections.Counter(l)"
py "collections.Counter(iter(input, ''))"
r=range(20, 2*10**7);
print(choices(r, (1/x for x in r)))
from guppy import hpy; from random import choices; h=hpy(); print(h.heap()); r=range(20, 2*10**7); print(choices(r, (1/x for x in r))); print(h.heap())
Partition of a set of 257681 objects. Total size = 30586285 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 77410 30 8264794 27 8264794 27 str
1 69723 27 5198776 17 13463570 44 tuple
2 28709 11 2133716 7 15597286 51 bytes
3 14447 6 2089272 7 17686558 58 types.CodeType
4 15188 6 2065568 7 19752126 65 function
5 2013 1 1932488 6 21684614 71 type
6 3316 1 1515992 5 23200606 76 dict (no owner)
7 684 0 937144 3 24137750 79 dict of module
8 2013 1 932560 3 25070310 82 dict of type
9 1866 1 633536 2 25703846 84 set
<863 more rows. Type e.g. '_.more' to view.>
[9585326]
Partition of a set of 257636 objects. Total size = 30579517 bytes.
Index Count % Size % Cumulative % Kind (class / dict of class)
0 77406 30 8264562 27 8264562 27 str
1 69724 27 5198832 17 13463394 44 tuple
2 28709 11 2133716 7 15597110 51 bytes
3 14447 6 2089272 7 17686382 58 types.CodeType
4 15186 6 2065296 7 19751678 65 function
5 2013 1 1932488 6 21684166 71 type
6 3310 1 1514552 5 23198718 76 dict (no owner)
7 684 0 937144 3 24135862 79 dict of module
8 2013 1 932560 3 25068422 82 dict of type
9 1866 1 633536 2 25701958 84 set
<859 more rows. Type e.g. '_.more' to view.>
def choices(self, population, weights=None, *, cum_weights=None, k=1):
"""Return a k sized list of population elements chosen with replacement.
If the relative weights or cumulative weights are not specified,
the selections are made with equal probability.
"""
random = self.random
if cum_weights is None:
if weights is None:
_int = int
total = len(population)
return [population[_int(random() * total)] for i in range(k)]
cum_weights = list(_itertools.accumulate(weights))
elif weights is not None:
raise TypeError('Cannot specify both weights and cumulative weights')
if len(cum_weights) != len(population):
raise ValueError('The number of weights does not match the population')
bisect = _bisect.bisect
total = cum_weights[-1]
hi = len(cum_weights) - 1
return [population[bisect(cum_weights, random() * total, 0, hi)]
for i in range(k)]
def choices(a=20, b=2*10**7, k=1):
from random import Random
import itertools
from bisect import bisect
random = Random().random
n = b - a
population = range(a, b)
weights = (1/x for x in population)
cum_weights = list(itertools.accumulate(weights))
# get_weight = lambda idx: 1 / (a + idx)
# get_cum_weight = lambda idx: ????
total = cum_weights[-1]
hi = len(cum_weights) - 1
return [
population[bisect(cum_weights, random() * total, 0, hi)]
for i in range(k)
]
cum_weights = list(itertools.accumulate(weights))
С[n]=1/(a+0)+1/(a+1)+1/(a+2)+...+1/(a+n)