Я понимаю, что они оба по сути одно и то же, но с точки зрения стиля, что лучше (более Pythonic) для создания пустого списка или dict?
Я понимаю, что они оба по сути одно и то же, но с точки зрения стиля, что лучше (более Pythonic) для создания пустого списка или dict?
Ответы:
Что касается скорости, то здесь нет конкуренции для пустых списков / диктов:
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
и для непустого:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
Кроме того, использование скобок позволяет вам использовать понимание списка и словаря, что может быть достаточной причиной.
timeit()
функция сообщает общее количество времени на выполнение указанного количества итераций, которое установлено 1000000
по умолчанию. Таким образом, приведенные выше примеры - это количество секунд для выполнения фрагмента кода миллион раз. Например timeit('dict()', number=1) // -> 4.0531158447265625e-06
(одна итерация) while timeit('dict()') // -> 0.12412905693054199
(миллион итераций)
На мой взгляд , []
и {}
являются наиболее вещий и машиночитаемые способы создания пустых списков / dicts.
Однако будьте осторожны set()
, например:
this_set = {5}
some_other_set = {}
Может сбивать с толку. Первый создает набор с одним элементом, второй создает пустой dict, а не набор.
{}
всегда создает пустой dict. {1,2,3}
создает набор в 2.7+, но является синтаксической ошибкой в 2.6
более ранних версиях.
some_epic_set
, указывающим на пустой dict
объект ... это не пустой набор. Для пустого набора нужно использовать set()
.
{5}
создается набор с одним элементом, 5
и {}
это пустой dict.
{*()}
для создания пустого set
с буквальным синтаксисом. Я называю это одноглазым оператором обезьяны. :-)
ДИКТ литерал может быть крошечными немного быстрее , так как его байткод короче:
In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()
In [4]: dis.dis(a)
1 0 BUILD_MAP 0
3 RETURN_VALUE
In [5]: dis.dis(b)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
То же самое относится и к list
vs[]
CALL_FUNCTION
занимает по крайней мере столько же времени, сколько BUILD_MAP
(по сути вызываемая функция BUILD_MAP
), а LOAD_GLOBAL
занимает лишь дополнительные накладные расходы.
ИМХО, использование list()
и dict()
делает ваш Python похожим на C. Ух.
В случае разницы между [] и list () есть ловушка, на которую я не видел, чтобы кто-нибудь указал. Если вы используете словарь в качестве члена списка, они дадут совершенно разные результаты:
In [1]: foo_dict = {"1":"foo", "2":"bar"}
In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]
In [3]: list(foo_dict)
Out [3]: ['1', '2']
[foo_dict]
при использовании list((foo_dict,))
. list()
Метод принимает итератор , поскольку это единственный параметр и итерацию над ним , чтобы добавить элементы в список. Это вызовет аналогичную ловушку, сделав list(some_list)
список более плоским.
list () и [] работают по-разному:
>>> def a(p=None):
... print(id(p))
...
>>> for r in range(3):
... a([])
...
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
... a(list())
...
139969725367296
139969725367552
139969725367616
list () всегда создает новый объект в куче, но [] может повторно использовать ячейку памяти по многим причинам.
есть одно различие в поведении между [] и list (), как показано в примере ниже. нам нужно использовать list (), если мы хотим получить список чисел, иначе мы получим объект карты! Не знаю, как это объяснить.
sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth)
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list
type(sth2[0]) # map
sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int
Пара квадратных скобок обозначает один из объектов списка или индекс индекса my_List [x].
Пара фигурных скобок обозначает объект словаря.
a_list = ['вкл', 'выкл', 1, 2]
a_dict = {вкл: 1, выкл: 2}
В основном это вопрос выбора. Это вопрос предпочтений.
Однако обратите внимание, что, например, если у вас есть цифровые клавиши, вы не можете этого сделать:
mydict = dict(1="foo", 2="bar")
Ты должен сделать:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(без кавычек для ключей).
list(i for i in range(10) if i % 2)