실제로 파이썬에서 목록을 연결하는 두 가지 방법이있을 수 있습니다. 한 가지 방법은 extend () 메소드를 사용하는 것입니다.
a = [1, 2]
b = [2, 3]
b.extend(a)
다른 하나는 더하기 (+) 연산자를 사용합니다.
b += a
이제 두 가지 옵션 중 어느 것이 연결을 나열하는 ‘파이 토닉’방법이며 둘 사이에 차이점이 있습니까?
답변
바이트 코드 수준의 유일한 차이점 .extend
은 함수 호출과 관련 이 있다는 것입니다.이 함수 호출은 Python보다 약간 비쌉니다 INPLACE_ADD
.
이 작업을 수십억 번 수행하지 않으면 걱정할 것이 없습니다. 그러나 병목 현상이 다른 곳에있을 수 있습니다.
답변
로컬 변수가 아닌 변수에 + =를 사용할 수 없습니다 (변수는 함수에 대해 로컬 변수가 아니며 전역 변수가 아닙니다)
def main():
l = [1, 2, 3]
def foo():
l.extend([4])
def boo():
l += [5]
foo()
print l
boo() # this will fail
main()
그것은을 위해 때문이다 확장 변수를로드 할 경우 컴파일러를 l
사용하여 LOAD_DEREF
명령을하지만, +를 위해 =이 사용합니다 LOAD_FAST
– 당신은 얻을*UnboundLocalError: local variable 'l' referenced before assignment*
답변
함수 호출을 연결할 수는 있지만 함수 호출을 직접 + = 할 수는 없습니다.
class A:
def __init__(self):
self.listFoo = [1, 2]
self.listBar = [3, 4]
def get_list(self, which):
if which == "Foo":
return self.listFoo
return self.listBar
a = A()
other_list = [5, 6]
a.get_list("Foo").extend(other_list)
a.get_list("Foo") += other_list #SyntaxError: can't assign to function call
답변
나는 numpy와 관련하여 약간의 차이가 있다고 말할 것입니다 (방금 질문은 numpy 배열이 아닌 두 목록을 연결하는 것에 대해 질문하는 것을 보았지만 초보자와 같은 문제 일 수 있기 때문에 이것이 누군가를 도울 수 있기를 바랍니다. 예를 들어이 게시물에 대한 해결책을 찾는 사람).
import numpy as np
a = np.zeros((4,4,4))
b = []
b += a
오류와 함께 반환됩니다
ValueError : 피연산자를 셰이프 (0,)와 함께 브로드 캐스트 할 수 없습니다 (4,4,4)
b.extend(a)
완벽하게 작동
답변
로부터 CPython의 3.5.2 소스 코드 없음 큰 차이 :.
static PyObject *
list_inplace_concat(PyListObject *self, PyObject *other)
{
PyObject *result;
result = listextend(self, other);
if (result == NULL)
return result;
Py_DECREF(result);
Py_INCREF(self);
return (PyObject *)self;
}
답변
extend ()는 iterable *과 함께 작동하고 + =는 일부와 작동하지만 펑키 할 수 있습니다.
import numpy as np
l = [2, 3, 4]
t = (5, 6, 7)
l += t
l
[2, 3, 4, 5, 6, 7]
l = [2, 3, 4]
t = np.array((5, 6, 7))
l += t
l
array([ 7, 9, 11])
l = [2, 3, 4]
t = np.array((5, 6, 7))
l.extend(t)
l
[2, 3, 4, 5, 6, 7]
Python 3.6
* .extend ()가 iterable과 작동하지만 내가 틀렸다면 의견을 말하십시오.
답변
실제로 세 가지 옵션 ( ADD
, INPLACE_ADD
및) 간에 차이가 있습니다 extend
. 전자는 항상 느리지 만 다른 두 개는 거의 같습니다.
이 정보를 사용하여보다을 사용 하고 싶습니다.보다 extend
빠르며 ADD
, 귀하가하고있는 것보다 더 명확하게 보입니다 INPLACE_ADD
.
다음 코드를 몇 번 시도하십시오 (Python 3의 경우).
import time
def test():
x = list(range(10000000))
y = list(range(10000000))
z = list(range(10000000))
# INPLACE_ADD
t0 = time.process_time()
z += x
t_inplace_add = time.process_time() - t0
# ADD
t0 = time.process_time()
w = x + y
t_add = time.process_time() - t0
# Extend
t0 = time.process_time()
x.extend(y)
t_extend = time.process_time() - t0
print('ADD {} s'.format(t_add))
print('INPLACE_ADD {} s'.format(t_inplace_add))
print('extend {} s'.format(t_extend))
print()
for i in range(10):
test()
ADD 0.3540440000000018 s
INPLACE_ADD 0.10896000000000328 s
extend 0.08370399999999734 s
ADD 0.2024550000000005 s
INPLACE_ADD 0.0972940000000051 s
extend 0.09610200000000191 s
ADD 0.1680199999999985 s
INPLACE_ADD 0.08162199999999586 s
extend 0.0815160000000077 s
ADD 0.16708400000000267 s
INPLACE_ADD 0.0797719999999913 s
extend 0.0801490000000058 s
ADD 0.1681250000000034 s
INPLACE_ADD 0.08324399999999343 s
extend 0.08062700000000689 s
ADD 0.1707760000000036 s
INPLACE_ADD 0.08071900000000198 s
extend 0.09226200000000517 s
ADD 0.1668420000000026 s
INPLACE_ADD 0.08047300000001201 s
extend 0.0848089999999928 s
ADD 0.16659500000000094 s
INPLACE_ADD 0.08019399999999166 s
extend 0.07981599999999389 s
ADD 0.1710910000000041 s
INPLACE_ADD 0.0783479999999912 s
extend 0.07987599999999873 s
ADD 0.16435900000000458 s
INPLACE_ADD 0.08131200000001115 s
extend 0.0818660000000051 s