Задать вопрос
  • Как ускорить регулярные выражения в python?

    adugin
    @adugin Куратор тега Python
    Нужно увеличить кэш:
    >>> import re
    >>> re._MAXCACHE
    100
    >>> re._MAXCACHE = 3000
    >>> re._MAXCACHE
    3000

    Подозреваю, что при этом re.compile() в явном виде использовать не обязательно.
    Ответ написан
    Комментировать
  • Как склеить переменные в строку в python?

    adugin
    @adugin Куратор тега Python
    Используйте join():
    >>> from timeit import timeit
    >>> def f1(s1='foo', s2='bar'):
    	return ' - '.join((s1, s2))
    
    >>> f1()
    'foo - bar'
    >>> def f2(s1='foo', s2='bar'):
    	return '{0} - {1}'.format(s1, s2)
    
    >>> f2()
    'foo - bar'
    >>> def f3(s1='foo', s2='bar'):
    	return '%s - %s' % (s1, s2)
    
    >>> f3()
    'foo - bar'
    >>> timeit(f1)
    0.7238124336211288
    >>> timeit(f2)
    1.3038862714413124
    >>> timeit(f3)
    0.8215918286469828
    Ответ написан
    Комментировать
  • Как организовать обработку поля namedtuple при [первом] вызове?

    adugin
    @adugin Автор вопроса, куратор тега Python
    Пока удалось родить такое кривенькое решение. При каждом обращении атрибут пересчитывается заново. Хорошо бы добавить memoization. Но, по крайней мере, работает:
    >>> def namedtuplex(*args, **kwargs):
        def getitem(self, key):
            if type(key) is str:
                value = getattr(self, key)
            else:
                value = tuple.__getitem__(self, key)
            if type(value) is str:
                value = value.strip('"')
                try:
                    value = eval(value)
                except:
                    value = intern(value)
            return value
        ntuple = collections.namedtuple(*args, **kwargs)
        ntuple.__getitem__ = getitem
        return ntuple
    
    >>> XDR = namedtuplex('XDR', 'a b c d e f g')
    >>> xdr = XDR('"abc"', 'def', '5', '"3.14"', 2.71, [1,2], None)
    >>> xdr.a
    'abc'
    >>> xdr.b
    'def'
    >>> xdr.c
    5
    >>> xdr.d
    3.14
    >>> xdr.e
    2.71
    >>> xdr.f
    [1, 2]
    >>> xdr.g
    >>> xdr['a']
    'abc'
    >>> xdr['b']
    'def'
    >>> xdr['c']
    5
    >>> xdr['d']
    3.14
    >>> xdr['e']
    2.71
    >>> xdr['f']
    [1, 2]
    >>> xdr['g']
    >>>
    В зависимость от конкретного применения можно сделать что-то такое:
    eval(value.strip('"'))
    Либо разбирать непосредственно через int() и float() в блоках try..except.
    Ответ написан
    Комментировать
  • Как инвертировать словарь без использования дополнительной памяти?

    adugin
    @adugin Автор вопроса, куратор тега Python
    Пока додумался до такого метода:
    xcache = dict()
    while cache:
        	key, val = cache.iteritems().next()
        	xcache[cache.pop(key)] = key
    Такой способ в 3 раза величивает время исполнения скрипта (с 60 до 180 секунд на моём ноутбуке) по сравнению с традиционным методом инвертирования "в лоб". Есть ли способ лучше?

    Update #1: Тоже тормозит.
    xcache = dict()
    cpop = cache.pop
    while cache:
        key = cache.iterkeys().next()
        xcache[cpop(key)] = key
    del cache

    Update #2: Вот так скорость вернулась на значение 60 секунд. Что ещё?
    xcache = dict()
    cpop = cache.popitem
    while cache:
        key, val = cpop()
        xcache[val] = key
    del cache
    Ответ написан
    Комментировать
  • С чем сравнить число в python, чтобы в результате всегда было true/false?

    adugin
    @adugin Куратор тега Python
    >>> float('inf')
    inf
    >>> float('-inf')
    -inf
    >>> -float('inf')
    -inf
    >>> infinity = float('inf')
    >>> 42 < infinity
    True
    Ответ написан
    Комментировать
  • Какие витаминки употребляют IT-шники?

    adugin
    @adugin
    Для начала - приведите в норму режим и питание. Всё остальное - примочки.

    Отвечая непосредственно на вопрос:

    Тяжёлая артиллерия - пропейте курс витаминов Animal Pak от Universal Nutrition. Но Там реально конские дозировки, так что злоупотреблять не стоит. Но зато уже через две недели почувствуете существенный прирост энергичности.
    sportwiki.to/Animal_Pak_(Universal)

    Попроще, но тоже очень хорошие - Opti-Men от Optimum Nutrition:
    sportwiki.to/Opti-Men_(Optimum_Nutrition)

    Ну и в целом: http://sportwiki.to/Категория:Здоровье
    Ответ написан
    Комментировать
  • Как определить наименьшее уникальное значение в словаре?

    adugin
    @adugin Куратор тега Python
    Самое простое и эффективное решение без лишних действий:
    from collections import Counter
    
    def min_unique(dictionary):
        minval, result = float('inf'), None
        counter = Counter(dictionary.itervalues())
        for key, val in dictionary.iteritems():
            if (val < minval) and (counter[val] == 1):
                minval = val
                result = (key, val)
        return result
    
    data = {'a': 23, 'b': 26, 'c': 45, 'd': 23}
    print min_unique(data)

    Или так:
    from operator import itemgetter
    from itertools import ifilter
    
    def min_unique(dictionary):
        inverted = dict()
        for key, value in dictionary.iteritems():
            inverted[value] = None if value in inverted else key
        filtered = ifilter(itemgetter(1), inverted.iteritems())
        try:
            value, key = min(filtered, key=itemgetter(0))
        except ValueError:
            value, key = None, None
        return key, value

    Ещё интересный вариант с итераторами (узкое место - сортировка):
    from operator import itemgetter
    from itertools import groupby
    
    def min_unique(dictionary, ig=itemgetter(1)):
        grouped = groupby(sorted(dictionary.viewitems(), key=ig), key=ig)
        for key, entries in grouped:
            entry = entries.next()
            try:
                entries.next()
            except StopIteration:
                return entry
            else:
                continue
    Ответ написан
    2 комментария
  • Как на Python'е сделать так, чтобы программа сама могла создавать переменные, списки, кортежи и т.д.?

    adugin
    @adugin Куратор тега Python
    exec()
    eval()
    также посмотрите в исходники класса namedtuple модуля collections
    >>> exec('a = [1,2,3]')
    >>> a
    [1, 2, 3]
    Ответ написан
    Комментировать
  • Как выделить одну нужную мне букву?

    adugin
    @adugin
    4e08ad390d874f48a57c3a93d410f336.png
    Ответ написан
    Комментировать
  • Есть ли способ автоматически выставлять отступы в python?

    adugin
    @adugin Куратор тега Python
    А нечего в Notepad писать :) Используйте IDE или хотя бы Notepad++
    Ответ написан
  • Работа с анаграммами, как можно оптимизировать скрипт?

    adugin
    @adugin Куратор тега Python
    Расчёт анаграмм (permutations) здесь не требуется (пп. 2 и 3 - вводят в заблуждение).
    Поэтому скорость выполнения представленного ниже кода не зависит от длины слова.
    На базе в 20.000 слов выполняется мгновенно даже с 'antidisestablishmentarianism':
    from collections import Counter
    from itertools import ifilter
    
    def criteria(dictword):
        return (
            wlen == len(dictword) and
            wset == set(dictword) and
            wcnt == Counter(dictword)
        )
    
    while True:
    
        word = raw_input('\nEnter word: ')
        wlen, wset, wcnt = len(word), set(word), Counter(word)
    
        with open('thesaurus.txt') as f:
            thesaurus = (line.rstrip() for line in f)
            for dictword in ifilter(criteria, thesaurus):
                print dictword
    
        if word in {'exit', 'quit'}:
            break
    Ответ написан
    Комментировать
  • Как написать простую программу вычисления квадратных уравнений на Python?

    adugin
    @adugin Куратор тега Python
    1) Надо использовать float(), а не int()
    2) Конструкция 'from __future__ import division' тоже может пригодиться.

    >>> from math import sqrt
    >>> def solver():
        try:
            a, b, c = map(float, raw_input('Введите a, b, c через пробел: ').split())
        except:
            print 'На колу мочало - начинай сначала!'
        else:
            d = b*b - 4*a*c
            if d >= 0:
                sd = sqrt(d)
                root = lambda k: '{:.6f}'.format((-b+k*sd)/(2*a))
                solution = ' и '.join(set(map(root, (-1,1))))
            else:
                solution = 'уравнение не имеет решений'
            print 'Ответ: %s' % solution
    
    >>> solver()
    Введите a, b, c через пробел: 1, 2 3
    На колу мочало - начинай сначала!
    >>> solver()
    Введите a, b, c через пробел: 1 2 3
    Ответ: уравнение не имеет решений
    >>> solver()
    Введите a, b, c через пробел: 4 9 1
    Ответ: -0.117218 и -2.132782
    >>>
    Ответ написан
    Комментировать
  • Как правильно использовать отступы в python?

    adugin
    @adugin Куратор тега Python
    1) Вместо input() из соображений безопасности лучше использовать raw_input()
    >>> print 'Result: %s' % input('Expression: ')
    Expression: 2+3
    Result: 5
    
    >>> print 'Result: %s' % input('Expression: ')
    Expression: 1/0
    
    Traceback (most recent call last):
      File "<pyshell#3>", line 1, in <module>
        print 'Result: %s' % input('Expression: ')
      File "<string>", line 1, in <module>
    ZeroDivisionError: integer division or modulo by zero

    Но что гораздо хуже - через input() можно выполнять злонамеренные действия:
    >>> import os
    >>> input()
    os.remove('z:\\test.txt')
    >>>

    2) raw_input() возвращает str, поэтому дополнительное преобразование не нужно.
    3) Вместо флага running лучше использовать 'while True:' и break в нужном месте.
    Ответ написан
  • Как валидировать URL с помощью Python?

    adugin
    @adugin Куратор тега Python
    Выложите кусок кода и тестовый URL. Телепатов, к сожалению, нет...
    >>> import re
    >>> url = 'http://www.mail.ru/index.html'
    >>> parser = re.compile('^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$')
    >>> parser.findall(url)
    [('http://', 'www.mail', 'ru', '')]
    Ответ написан
  • Полная ли жесть данный код на python?

    adugin
    @adugin Куратор тега Python
    Лютый говнокодище - что у автора, что в комментах :)
    dlist = [('www.ya.ru', {1,2,3}), ('ya.ru', {4,5}), ('xxx.x', {6,7,8,9})]

    Если порядок элементов не важен, то эталонный код должен выглядеть так:
    from collections import defaultdict
    
    buffer = defaultdict(set)
    for domain, stuff in dlist:
        buffer[domain.lstrip('www.')].update(stuff)
    print buffer.items()

    Если порядок важен:
    from collections import OrderedDict
    
    buffer = OrderedDict()
    for domain, stuff in dlist:
        if domain.startswith('www.'):
            domain = domain[4:]
        buffer.setdefault(domain, set()).update(stuff)
    print buffer.items()

    И не надо лепить нечитабельные однострочники! Но если ради научного интереса:
    buffer = defaultdict(set)
    map(lambda (domain, stuff): buffer[domain.lstrip('www.')].update(stuff), dlist)
    print buffer.items()

    Или так:
    reduce(
        lambda buffer, (domain, stuff): buffer[domain.lstrip('www.')].update(stuff) or buffer,
        dlist,
        defaultdict(set)
    ).items()
    Ответ написан
  • Как сравнить ключи в словаре?

    adugin
    @adugin Куратор тега Python
    >>> items = [ 'photo_2560', 'photo_1280', 'width', 'album_id', 'post_id', 'date', 'owner_id', 'photo_807', 'photo_604', 'id', 'photo_130', 'text']
    >>> max((item for item in items if item.startswith('photo_')), key=lambda x: int(x[6:]))
    'photo_2560'
    Ответ написан
  • Как удалить запрещенные символы из строки?

    adugin
    @adugin Куратор тега Python
    >>> s = 'abc<def*gh?ikl'
    >>> s.translate(None, '\/:*?"<>|')
    'abcdefghikl'
    Ответ написан
    9 комментариев
  • Где найти скрипт советника купли-продажи валюты?

    adugin
    @adugin
    Очередной охотник быстренько заработать на форексе? Гуглить по словам MQL и MetaTrader.
    Ответ написан
    Комментировать
  • Кто получает удовольствие от Физики)?

    adugin
    @adugin
    Рекомендую курс Детлафа и Яворского:
    Detlaf.jpg
    Ответ написан
    Комментировать
  • Как отправить смайлики за минимальное количество операций?

    adugin
    @adugin Куратор тега Python
    Код на Python для расчёта "в лоб" (перебором) и выявления закономерностей:
    # -*- coding: utf-8 -*-
    
    import matplotlib.pyplot as plt
    from itertools import product
    
    def process(existing, required):
        for opcount in xrange(existing+required):
            for combo in product('dcv', repeat=opcount):
                buffer = 0
                smiles = existing
                data_y = [existing]
                for char in combo:
                    if char == 'd':
                        smiles -= 1
                    elif char == 'v':
                        smiles += buffer
                    else:
                        buffer = smiles
                    data_y.append(smiles)
                if smiles == required:
                    data_x = xrange(opcount+1)
                    plt.plot(data_x, data_y, linewidth=1)
                    print required, data_y
                    return ''.join(combo)
        return '-'
    
    for required in xrange(2, 101):
        plt.clf()
        plt.grid(True)
        plt.title('Target: %s' % required)
        plt.autoscale(enable=True, axis='both', tight=False)
        for existing in xrange(1, (required//2)+1):
            result = process(existing, required)
        plt.savefig('{:02d}.png'.format(required), dpi=96, bbox_inches='tight')

    Задача распадается на 2:
    1) Если M >= N div 2, то нужно удалить всё до половины, скопипастить, и по необходимости удалить 1 смайл.
    2) Если п.1 не выполняется, то нужно рассчитать делители N (если N простое - то взять следующие несколько чисел больше N) и спуститься к ближайшему наибольшему делителю N, который меньше M. Удалять смайлы, чтобы попадать в наблюдаемые на картинках горизонтальные уровни, соответствующие делителям.

    В общем случае решение не единственное - например, соседние группы D и V можно смешивать в любых последовательностях: DDVVV = VVVDD = VDVDV = ...

    N=12. Для M=5 видим DCVV (фиолетовая линия). Уровни (делители) - 6, 4, 3, 2, 1:
    042d326f2b1a45d2916c5ce012fca2f6.png
    N=28:
    c832673197de486aa072d81b56de27c4.png
    N=29:
    4e0ee3d81d9b47e38127cf8211c2c48f.png
    N=30:
    2629d000169449c1896414c348b61874.png
    N=71:
    5037b1d5028b4330aed51516ec81887f.png
    N=72:
    89fd833e066f423993665d4c54e8f6cc.png
    PDF со всеми картинками: dugin.org/dropbox/toster_188303.pdf (11 Mb)

    P.S. https://ru.wikipedia.org/wiki/Задача_о_ранце
    Ответ написан
    Комментировать