Python의 목록과 튜플

2024. 1. 2. 16:01python/basic

파이썬 목록

간단히 말하면 목록은 임의 개체의 모음으로, 다른 많은 프로그래밍 언어의 배열과 다소 유사하지만 더 유연합니다. 목록은 아래와 같이 쉼표로 구분된 개체 시퀀스를 대괄호([])로 묶어 Python에서 정의됩니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux']

print(a)
In [ ]:
a

Python 목록의 중요한 특징은 다음과 같습니다.

  • 목록은 순서가 지정됩니다.
  • 목록에는 임의의 개체가 포함될 수 있습니다.
  • 목록 요소는 인덱스로 액세스할 수 있습니다.
  • 목록은 임의의 깊이로 중첩될 수 있습니다.
  • 목록은 변경 가능합니다.
  • 목록은 동적입니다.

목록이 정렬됩니다

리스트는 단순한 객체의 모음이 아닙니다. 순서가 지정된 개체 모음입니다. 동일한 요소가 다른 순서로 있는 목록은 동일하지 않습니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux']
b = ['baz', 'qux', 'bar', 'foo']

a == b
In [ ]:
a is b
In [ ]:
[1, 2, 3, 4] == [4, 1, 3, 2]

목록에는 임의의 개체가 포함될 수 있습니다.

목록의 요소는 모두 동일한 유형일 수 있습니다. 또는 요소의 유형이 다양할 수 있습니다.

In [ ]:
a = [21.42, 'foobar', 3, 4, 'bark', False, 3.14159]

a

목록에는 함수, 클래스, 모듈과 같은 복잡한 객체도 포함될 수 있습니다.

In [ ]:
int
In [ ]:
len
In [ ]:
def foo():
    pass

foo
In [ ]:
import math

math
In [ ]:
a = [int, len, foo, math]

a

목록에는 0부터 컴퓨터 메모리가 허용하는 만큼의 개체 수에 제한이 없을 수 있습니다. 단일 개체가 포함된 목록을 싱글톤 목록이라고도 합니다.

목록 개체는 고유할 필요가 없습니다. 주어진 객체는 목록에 여러 번 나타날 수 있습니다.

In [ ]:
a = ['bark', 'meow', 'woof', 'bark', 'cheep', 'bark']

a

목록 요소는 인덱스로 액세스할 수 있습니다.

목록 인덱싱은 문자열과 마찬가지로 0부터 시작합니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a[0]
In [ ]:
a[1]
In [ ]:
a[5]

문자열 인덱싱에 관한 거의 모든 작업은 목록에서도 유사하게 작동합니다. 예를 들어, 네거티브 목록 색인은 목록 끝부터 계산됩니다.

 

 

a[-1]
In [ ]:
a[-6]

슬라이싱도 작동합니다.

In [ ]:
a[2:5]

문자열 슬라이싱의 다른 기능도 목록 슬라이싱과 유사하게 작동합니다.

  • 양수 인덱스와 음수 인덱스를 모두 지정할 수 있습니다.
In [ ]:
a[-5:-2]
In [ ]:
a[1:4]
In [ ]:
a[-5:-2] == a[1:4]
  • 첫 번째 인덱스를 생략하면 목록의 시작 부분에서 조각이 시작되고, 두 번째 인덱스를 생략하면 조각이 목록의 끝으로 확장됩니다.
In [ ]:
print(a[:4], a[0:4])
In [ ]:
print(a[2:], a[2:len(a)])
In [ ]:
a[:4] + a[4:] == a
  • 양수 또는 음수로 보폭을 지정할 수 있습니다.
In [ ]:
a[0:6:2]
In [ ]:
a[1:6:2]
In [ ]:
a[6:0:-2]
  • 목록을 뒤집는 구문은 문자열의 경우와 동일한 방식으로 작동합니다.
In [ ]:
a[::-1]
  • [:] 구문은 목록에 작동합니다. 그러나 이 작업이 목록에서 작동하는 방식과 문자열에서 작동하는 방식에는 중요한 차이가 있습니다.

s이 문자열인 경우 s[:]는 동일한 개체에 대한 참조를 반환합니다.

In [ ]:
s = 'foobar'

s[:]
In [ ]:
s[:] is s

반대로 a가 목록인 경우 a[:]는 a의 복사본인 새 개체를 반환합니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a[:]
In [ ]:
a[:] is a
  • in 및 not in 연산자
In [ ]:
'qux' in a
In [ ]:
'thud' not in a
  • 연결(+) 및 복제(*) 연산자
In [ ]:
a + ['grault', 'garply']
In [ ]:
a * 2
  • len(), min() 및 max() 함수
In [ ]:
len(a)
In [ ]:
min(a)    # 알파벳 순
In [ ]:
max(a)

문자열과 목록이 그렇게 비슷하게 동작하는 것은 우연이 아닙니다. 둘 다 iterable이라고 하는 보다 일반적인 객체 유형의 특별한 경우입니다.

그런데 위의 각 예에서 목록은 작업이 수행되기 전에 항상 변수에 할당됩니다. 하지만 목록 리터럴에서도 작업할 수 있습니다.

In [ ]:
['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][2]
In [ ]:
['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1]
In [ ]:
'quux' in ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
In [ ]:
['foo', 'bar', 'baz'] + ['qux', 'quux', 'corge']
In [ ]:
len(['foo', 'bar', 'baz', 'qux', 'quux', 'corge'][::-1])

이 문제에 대해서는 문자열 리터럴을 사용하여 마찬가지로 수행할 수 있습니다.

In [ ]:
'If Comrade Napoleon says it, it must be right.'[::-1]

목록은 중첩될 수 있음

목록에는 하위 목록이 포함될 수 있으며, 하위 목록에는 하위 목록 자체가 포함될 수 있으며 임의의 깊이까지 포함될 수 있습니다.m

In [ ]:
x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']

x
In [ ]:
x[1]
In [ ]:
x[1][0]
In [ ]:
x[1][1]
In [ ]:
x[3][0]
In [ ]:
x[1][1][0]
In [ ]:
x[1][1][-1]
In [ ]:
x[3][::-1]
In [ ]:
'ddd' in x
In [ ]:
'ddd' in x[1]
In [ ]:
'ddd' in x[1][1]

'ddd'은 x 또는 x[1]의 요소 중 하나가 아닙니다. 이는 하위 목록 x[1][1]의 직접 요소일 뿐입니다.

목록은 변경 가능합니다

단일 목록 값 수정

목록의 단일 값은 인덱싱 및 간단한 할당으로 대체될 수 있습니다. 목록 항목은 del 명령으로 삭제할 수 있습니다

여러 목록 값 수정

a[m:n] = <iterable>

In [ ]:
a[1:4]
In [ ]:
a[1:4] = [1.1, 2.2, 3.3, 4.4, 5.5]
a
In [ ]:
a[1:6] = ['Bark!']

a
In [ ]:
a = [1, 2, 3]
a[1] = [2.1, 2.2, 2.3]

a

빈 목록에 적절한 조각을 할당하여 목록 중간에서 여러 요소를 삭제할 수 있습니다. 동일한 슬라이스에 del 문을 사용할 수도 있습니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
a[1:5] = []

a
In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
del a[1:5]

a
목록에 항목 추가 또는 추가

추가 항목은 + 연결 연산자 또는 += 증대 할당 연산자 를 사용하여 목록의 시작이나 끝에 추가할 수 있습니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a += ['grault', 'garply']
a
In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a = [10, 20] + a
a

목록은 다른 목록과 연결되어야 하므로 요소를 하나만 추가하려면 해당 요소를 싱글톤 목록으로 지정해야 합니다.

In [ ]:
a += [20]
a

참고: 기술적으로 목록이 다른 목록과 연결되어야 한다고 말하는 것은 정확하지 않습니다. 더 정확하게 말하면 목록은 반복 가능한 객체와 연결되어야 합니다. 물론 목록은 반복 가능하므로 목록을 다른 목록과 연결하는 데 효과적입니다.

문자열도 반복 가능합니다. 단일 문자열만 추가하려면 'corge' 목록 끝에 해당 문자열을 단일 목록으로 지정해야 합니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux']
a += ['corge']
a

목록을 수정하는 방법

  • a.append() : a 목록 끝에 개체를 추가합니다
In [ ]:
a = ['a', 'b']
a.append(123)
a
  • 연산자를 사용하여 목록에 연결할 때 대상 피연산자가 반복 가능한 경우 해당 요소가 분리되어 목록에 개별적으로 추가된다는 점을 기억하세요.
In [ ]:
a = ['a', 'b']
a + [1, 2, 3]

.append() 방법은 그런 식으로 작동하지 않습니다! iterable이 .append()를 사용하여 목록에 추가되면 단일 객체로 추가됩니다.

In [ ]:
a = ['a', 'b']
a.append([1, 2, 3])
a

따라서 .append()을 사용하면 문자열을 단일 엔터티로 추가할 수 있습니다.

In [ ]:
a = ['a', 'b']
a.append('foo')
a
  • a.extend() : .extend() 도 목록 끝에 추가되지만 인수는 반복 가능해야 합니다. 의 항목은 개별적으로 추가됩니다.
In [ ]:
a = ['a', 'b']
a.extend([1, 2, 3])
a

즉, .extend()은 + 연산자처럼 동작합니다. 보다 정확하게는 목록을 수정하므로 += 연산자처럼 동작합니다.

  • a.insert(, ) : 개체를 a 목록의 지정된 에 삽입합니다.
In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
a.insert(3, 3.14159)
a
  • a.remove() : 목록에서 개체를 제거합니다.
In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
a.remove('baz')
a
In [ ]:
a.remove('Bark!')
  • a.pop(index=-1) : 목록에서 요소를 제거합니다.

이 방법은 .remove()와 두 가지 측면에서 다릅니다.

  1. 객체 자체가 아닌 제거할 항목의 인덱스를 지정합니다.
  2. 이 메서드는 제거된 항목이라는 값을 반환합니다.

a.pop()단순히 목록의 마지막 항목을 제거합니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a.pop()
In [ ]:
a

선택적 <index> 매개변수가 지정된 경우 해당 색인의 항목이 제거되고 반환됩니다. <index> 문자열 및 목록 색인과 마찬가지로 음수일 수 있습니다.

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a.pop(1)
In [ ]:
a
In [ ]:
a.pop(-3)
In [ ]:
a

<index>의 기본값은 -1이므로 a.pop(-1)는 a.pop()과 동일합니다.

목록은 동적이다

In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']

a[2:2] = [1, 2, 3]
a += [3.14159]
a
In [ ]:
a = ['foo', 'bar', 'baz', 'qux', 'quux', 'corge']
a[2:3] = []
del a[0]
a

파이썬 튜플

튜플 정의 및 사용

튜플은 다음 속성을 제외하고 모든 측면에서 목록과 동일합니다.

  • 튜플은 요소를 대괄호([]) 대신 소괄호(())로 묶어 정의합니다.
  • 튜플은 변경할 수 없습니다.

다음은 튜플 정의, 인덱싱 및 슬라이싱을 보여주는 간단한 예입니다.

In [ ]:
t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
In [ ]:
t[0]
In [ ]:
t[-1]
In [ ]:
t[1::2]
In [ ]:
t[::-1]

목록에 대해 배운 모든 것(순서가 지정되어 있고, 임의의 개체를 포함할 수 있으며, 인덱싱 및 슬라이스가 가능하고, 중첩될 수 있음)은 튜플에도 적용됩니다. 하지만 수정할 수는 없습니다.

In [ ]:
t = ('foo', 'bar', 'baz', 'qux', 'quux', 'corge')
t[2] = 'Bark!'

리스트 대신 튜플을 사용하는 이유는 무엇입니까?

  • 동등한 목록보다 튜플을 조작할 때 프로그램 실행이 더 빠릅니다.(목록이나 튜플이 작을 때는 눈에 띄지 않을 것입니다.)
  • 때로는 데이터가 수정되는 것을 원하지 않을 때도 있습니다. 컬렉션의 값이 프로그램 수명 동안 일정하게 유지되어야 하는 경우 목록 대신 튜플을 사용하면 실수로 수정되는 것을 방지할 수 있습니다.
  • 또 다른 Python 데이터 유형인 사전이 있습니다. 이 유형은 구성 요소 중 하나로 변경할 수 없는 유형의 값이 필요합니다. 이 목적으로 튜플을 사용할 수 있지만 목록은 사용할 수 없습니다.
In [ ]:
t = ()
type(t)
In [ ]:
t = (2)
type(t)

싱글톤 튜플을 정의하고 싶다고 Python에 알리려면 닫는 괄호 바로 앞에 후행 쉼표()를 포함하세요.

In [ ]:
t = (2,)
type(t)

튜플 할당, 패킹 및 언패킹

In [ ]:
t = ('foo', 'bar', 'baz', 'qux')

t
In [ ]:
t[0]
In [ ]:
t[-1]

"포장된" 개체가 이후에 새 튜플에 할당되면 개별 항목은 튜플의 개체로 "압축 해제"됩니다. :

In [ ]:
(s1, s2, s3, s4) = t
s1
In [ ]:
s4

압축을 풀 때 왼쪽의 변수 개수는 튜플의 값 개수와 일치해야 합니다. 패킹과 언패킹을 하나의 명령문으로 결합하여 복합 할당을 만들 수 있습니다.

In [ ]:
(s1, s2, s3, s4) = ('foo', 'bar', 'baz', 'qux')
s1
In [ ]:
x1, x2, x3 = 4, 5, 6
x1, x2, x3

대부분의 프로그래밍 언어에서는 다음과 같이 스왑이 발생하는 동안 값 중 하나를 임시 변수에 저장해야 합니다. Python에서는 단일 튜플 할당으로 교체를 수행할 수 있습니다.

In [ ]:
a = 'foo'
b = 'bar'
a, b
In [ ]:
# Magic time!
a, b = b, a

a, b
In [ ]:
출처 : https://realpython.com/python-lists-tuples