Найти - Пользователи
Полная версия: Кейса нет..... какая альтернатива
Начало » Python для новичков » Кейса нет..... какая альтернатива
1 2 3 4
zahar
Всем привет. Есть небольшой скрипт, но вот внешний вид оставляет желать лучшего, считаю есть альтернативное решение, но мозгов не хватает. Вот кусок кода. в итоге надо посчитать количество вхождений.
...........
if ff['status'] == '5' or ff['status'] == '6':
                if ff['attr'] == 'AAAAA':
                    x += 1 # нужно посчитать количество
                if ff['attr'] == 'BBBBB':
                    y += 1
                if ff['attr'] == 'CCCCC':
                    z += 1
                if ff['attr'] == 'DDDDD':
                    q += 1
                if ff['attr'] == 'EEEEE':
                    w += 1
        print 'AAAAA', x
        print 'BBBBB', y
        print 'CCCCC', z
        print 'DDDDD', q
        print 'EEEEEE', w
Такой подход работает, но он мне в корне не нравиться. Значения ‘AAAAA’, ‘' ’BBBBB', ‘CCCCC’, ‘DDDDD’, ‘EEEEEE’ постоянные, поидее их можно загнать в список или кортеж.
JOHN_16
from collections import Counter
counter=Counter()
if ff['status'] in ('5', '6'):
    counter[ff['attr']]+=1
print counter
zahar
Спс, как всегда все просто.
ЗЫЖ и странно что я написал if ff == ‘5’ or ff == ‘6’: а не if ff in ('5', ‘6’):
JOHN_16
zahar
если вам кто то помог на этом форуме ставьте плюсик в карму, ведь человек тратил свое время на решение вашего вопроса.
Isem
На будущее, надо писать не так:
if something in (case, case2, ..., case3):
а так:
if something in {case, case2, ..., case3}:

Если case-ы - константы.

И плюсики ставить вовсе необязательно, достаточно сказать спасибо.
JOHN_16
Isem
На будущее, надо писать не так:
насколько это критично по вашему?
py.user.next
JOHN_16
насколько это критично
поиск во множестве - O(1), в кортеже - O(n)
при количестве элементов и повторных вызовах будет видно разницу (хотя не факт, в питоне не всегда всё логично)
Isem
JOHN_16
насколько это критично по вашему?
Как правильно отметил py.user.next, чем больше элементов, тем критичнее. Кроме того, начиная, кажется, с версии 3.2, конструкция value in {v1,v2, .., v3} отлавливается интерпретатором и оптимизируется.
JOHN_16
Давайте попробуем разведку боем. Маленький код на Python2. Перечисление:

import datetime
def timeit(func, *args):
    t1=datetime.datetime.now()
    func(*args)
    print datetime.datetime.now()-t1
data_l=range(int(1e7*2))
data_t=tuple(data_l)
data_s=set(data_l)
def l(var):
    a=0
    for i in var:
        a+=1
timeit(l, data_l)
timeit(l, data_t)
timeit(l, data_s)

Проверка на вхождение (тот же поиск):
def search(data):
    int(1e7*2)/2 in data
timeit(search, data_l)
timeit(search, data_t)
timeit(search, data_s)
Результаты:
Перечисление:
0:00:01.157000
0:00:01.156000
0:00:01.297000
Поиск:
0:00:00.281000
0:00:00.234000
0:00:00

1) Отсюда можно сделать вывод о том что множества хороши при поиске,но не при перечислении.
2) Раз уж мы говорим о больших массивах, то разница между range(int(1e7)) и set(xrange(int(1e7))) по занимаемой памяти у меня (WinXP) составляет 157.3 и 247.3Мб =90 Мб (или 57%), что составляет внушительную лишнюю нагрузку.
Поэтому мой вывод такой: для каждой цели хороши свои средства. Если не прав где то - поправьте меня, я человек = я могу ошибаться :-)
py.user.next
#!/usr/bin/env python3
 
import timeit
 
def f1():
    for c in 'abcd':
        c in {'a', 'b', 'c', 'd'}
 
def f2():
    for c in 'abcd':
        c in ('a', 'b', 'c', 'd')
 
t1 = timeit.Timer('f1()', 'from __main__ import f1')
t2 = timeit.Timer('f2()', 'from __main__ import f2')
 
for t in t1, t2:
    print(t.repeat(3))

[guest@localhost py]$ ./timecmp.py 
[0.4793789889990876, 0.47658576700086996, 0.4846548969999276]
[0.7281753709994518, 0.7266200249996473, 0.7135826749999978]
[guest@localhost py]$
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB