Добавить дополнительные элементы в список понимания - PullRequest
0 голосов
/ 24 мая 2018

У меня есть такой список:

a = ['orange', 'apple', 'banana']

, и из этого я строю другой список кортежей, используя простое понимание списка :

b = [(key, key.upper()) for key in a]

результат выглядит примерно так:

b = [('orange', 'ORANGE'), ('apple', 'APPLE'), ('banana', 'BANANA')]

Теперь мне нужно вставить еще один кортеж в начале (или в конце, например) вновь созданного списка b: ('---', None).

Вот два простых решения:

# Solution 1
b = [('---', None)] + b

# Solution 2 
b.insert(0, ('---', None))

Вопрос:
Есть ли способ выполнить то же самое непосредственно из конструкции понимания списка?
Может что-токак это (псевдокод) может быть возможно в Python?

b = [('---', None), (key, key.upper()) for key in a]

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Да, используя генераторные понимания:

b = [('---', None), *((key, key.upper()) for key in a)]

Вместо использования генераторского понимания вы могли бы также использовать списочное понимание.Преимущество использования генератора пониманий состоит в том, что они не создают новый список, а раздают предметы по одному.Если ваш список (a) большой, это может повлиять на использование памяти и / или производительность.

Использование звездочки («оператора сплат») для распаковки такой последовательности - PEP448 - Дополнительные обобщения распаковки .Он позволяет использовать * не только в вызовах функций, но и в списках, генераторе и наборах пониманий (то же самое относится к ** и словарным представлениям).

0 голосов
/ 24 мая 2018

Преждевременная оптимизация - корень всего зла

Определенная вами операция, скорее всего, не ваше узкое место.Использование умного понимания списка, которое позволяет вам использовать одно выражение, не решает проблему, связанную с производительностью.Ниже приведена демонстрация с 3 миллионами предметов в вашем списке.

Если вам нужно повторно добавить элементы в ваш список слева, я рекомендую вам использовать collections.deque.Обратите внимание, что deque имеет сложность O (1) для appendleft, а списки имеют производительность O (n) для insert(0, value).

from collections import deque

a = ['orange', 'apple', 'banana']*1000000

def l3v(a):
    return [('---', None), *((key, key.upper()) for key in a)]

def jpp(a):
    b = deque([(key, key.upper()) for key in a])
    b.appendleft(('---', None))
    return list(b)

def original(a):
    return [('---', None)] + [(key, key.upper()) for key in a]

def original2(a):
    b = [(key, key.upper()) for key in a]
    b.insert(0, ('---', None))
    return b

%timeit l3v(a)        # 1.35 s per loop
%timeit jpp(a)        # 1.23 s per loop
%timeit original(a)   # 1.17 s per loop
%timeit original2(a)  # 1.14 s per loop
0 голосов
/ 24 мая 2018

Попробуйте if if с пониманием списка.Как показано ниже

b = [(a[i],a[i].upper()) if i < len(a) else ('---',None)  for i in range(len(a)+1)]

Надеюсь, это поможет.

Happy Coding:)

...