2013-12-10 5 views
12

Q1 - a set()generator expression или set comprehension? (Или они же Если да, list & dict постижений также соответствующий тип отливка на генераторах?)Как работают Python Set Comprehensions?

my_set = {x for x in range(10)} 

Q2 - ли оценка рассмотреть повторяющиеся значения & затем удалить их, применяя set()?

dup_set = {x for x in [0, 1, 2, 0, 1, 2]} 

выполняет ли понимание (скорость-накрест) лучше, чем обычные for петли?

Обновление - Я попытался использовать timeit для сравнения скорости. Не уверен, что я просто (справедливо) об этом.

C:\>python -m timeit "s = set()" "for x in range(10):" " 
    s.add(x)" 
100000 loops, best of 3: 2.3 usec per loop 

C:\>python -m timeit "s = {x for x in range(10)}" 
1000000 loops, best of 3: 1.68 usec per loop 

Теперь, используя некоторые условными

C:\>python -m timeit "s = set()" "for x in range(10):" " 
    if x%2: s.add(x)" 
100000 loops, best of 3: 2.27 usec per loop 

C:\>python -m timeit "s = {x for x in range(10) if x%2}" 
1000000 loops, best of 3: 1.83 usec per loop 

Таким образом, существует довольно некоторая разница, это связано с функциональностью быть HARDCODED в c?

+1

Возможно, вы можете использовать timeit (http://docs.python.org/2/library/timeit.html) или создать функцию синхронизации времени с модулем времени, чтобы узнать разницу во времени/скорости – Totem

ответ

7

Q1: Да, да, да и да. Или, по крайней мере, они ведут себя так. Это немного отличается, если вы посмотрите на байт-код. Давайте разборке этот код (Python 2.7):

def list_comp(l): 
    return [x+1 for x in l] 

def dict_comp(l): 
    return {x+1:0 for x in l} 

def set_comp(l): 
    return {x+1 for x in l} 

def generator(l): 
    return (x+1 for x in l) 

Это то, что вы получите:

Disassembly of list_comp: 
    2   0 BUILD_LIST    0 
       3 LOAD_FAST    0 (l) 
       6 GET_ITER    
     >> 7 FOR_ITER    16 (to 26) 
      10 STORE_FAST    1 (x) 
      13 LOAD_FAST    1 (x) 
      16 LOAD_CONST    1 (1) 
      19 BINARY_ADD   
      20 LIST_APPEND    2 
      23 JUMP_ABSOLUTE   7 
     >> 26 RETURN_VALUE 
Disassembly of dict_comp: 
    5   0 LOAD_CONST    1 (<code object <dictcomp> at 029DEE30) 
       3 MAKE_FUNCTION   0 
       6 LOAD_FAST    0 (l) 
       9 GET_ITER    
      10 CALL_FUNCTION   1 
      13 RETURN_VALUE 
Disassembly of set_comp: 
    8   0 LOAD_CONST    1 (<code object <setcomp> at 029DECC8) 
       3 MAKE_FUNCTION   0 
       6 LOAD_FAST    0 (l) 
       9 GET_ITER    
      10 CALL_FUNCTION   1 
      13 RETURN_VALUE 
Disassembly of generator: 
11   0 LOAD_CONST    1 (<code object <genexpr> at 02A8FD58) 
       3 MAKE_FUNCTION   0 
       6 LOAD_FAST    0 (l) 
       9 GET_ITER    
      10 CALL_FUNCTION   1 
      13 RETURN_VALUE      

Байткод едва то же самое для Dict comprenhension, установленного понимания и генератора. Все они загружают объект кода (<dictcomp>, <setcomp> или <genexpr>), а затем выполняют функцию вызова из него. Понимание списков отличается тем, что генерирует байт-код, соответствующий вашему пониманию списка. На этот раз он интерпретируется и, следовательно, не является родным.

Q2: На самом деле он не учитывает повторяющиеся значения, так как создает понимание с предоставленным вами списком. И затем он создает набор с пониманием.

О сроках: Список/Dict/Set понимает, как правило, быстрее, чем что-либо еще. Даже если они интерпретируются, генерируемый байт-код оптимизирован для большинства случаев со специальными инструкциями байт-кода, такими как SET_ADD, LIST_APPEND или MAP_ADD.

+0

, написанную на 'C '?? –

+0

Я не уверен, я проверю это. – Vincent

+3

очевидно, что он написан в зависимости от того, какой питон вы используете (CPython, IronPython, Jython, PyPy и т. Д.). однако важным моментом является то, что он не является интуитивным. –

Смежные вопросы