>백엔드 개발 >파이썬 튜토리얼 >Python 목록 및 튜플에 대한 자세한 설명(예제와 함께 자세한 설명)

Python 목록 및 튜플에 대한 자세한 설명(예제와 함께 자세한 설명)

WBOY
WBOY앞으로
2022-03-09 18:23:063514검색

이 기사에서는 주로 목록과 튜플과 관련된 문제를 소개하는 python에 대한 관련 지식을 제공합니다. 먼저 목록과 튜플의 기본 사용법을 간략하게 이해하겠습니다. 모두에게 도움이 되십시오.

Python 목록 및 튜플에 대한 자세한 설명(예제와 함께 자세한 설명)

추천 학습: python 학습 튜토리얼

머리말

실제 개발에서는 쉽게 사용할 수 있도록 데이터 세트를 저장해야 하는 경우가 많습니다. 다른 언어를 공부한 적이 있다면 여러 개의 데이터를 저장할 수 있는 배열(Array)의 데이터 구조를 알 수 있으며, 배열 첨자를 통해 접근 데이터를 얻을 수 있다. Python 개발자라면 데이터 저장을 위해 보다 유연한 목록과 튜플을 사용할 수 있습니다. 먼저 목록과 튜플의 기본 사용법을 간략하게 이해해 보겠습니다.

List

목록은 동적이며 길이를 변경할 수 있고 요소를 마음대로 추가, 수정 또는 삭제할 수 있습니다.

목록 초기화

a = list()
b = []
# 可以通过range快速创建list
c = list(range(1,6))
print("a:", a)
print("b:", b)
print("c:", c)

# a: []
# b: []
# c: [1, 2, 3, 4, 5]

요소 추가

append: 목록 끝에 요소 추가

>>l = []
>>l.append("python")
>>l
['python']

extend: 반복 가능한 객체의 모든 요소로 목록 확장

>>l = ["python"]
>>t = ["java"]
>>l.extend(t)
>>l
['python', 'java']

insert: 주어진 위치에 요소 삽입 위치 요소. 첫 번째 매개변수는 삽입할 요소의 인덱스이므로 list_name.insert(0, x)는 목록의 헤드를 삽입하고.insert(0, x) 插入列表头部

>>l = ["python", "java"]
>>l.insert(1,"go")
>>l
['python', 'go', 'java']

删除元素

remove(x):从列表中删除值为x的第一项。 如果没有需要删除的值,那就抛出异常

>>l = ["python", "java"]
>>l.remove("java")
>>l
['python']
>>l.remove("test")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: list.remove(x): x not in list

pop: 删除列表中给定位置的元素并返回它。如果没有给定位置,pop() 将会删除并返回列表中的最后一个元素

>>l = ["python", "java", "go"]
>>l.pop()
'go'
>>l
['python', 'java']
>>l.pop(1)
'java'
>>l.pop(1)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
IndexError: pop index out of range

del: Python 中的关键字,专门用来执行删除操作,它不仅可以删除整个列表,还可以删除列表中的某些元素

>>l = ["python", "java", "go", "js"]
>>del l[0:1]
>>l
['java', 'go', 'js']
>>del l[0]
>>l
['go', 'js']

clear(): 移除列表中的所有元素。等价于 del a[:]

>>l = ["python", "java", "go", "js"]
>>l.clear()
>>l
[]

ps: 这里注意和del 的区别, clear是清空, del list_name 是删除,内存也释放

修改元素

修改单个可以通过下标的方法

>>l = ["python", "go", "java"]
>>l[0] = "PYTHON"
>>l
['PYTHON', 'go', 'java']

修改一组数据可以通过切片的方式

>>l = ["python", "go", "java"]
>>l[0:2] = "PYTHON", "GO"
>>l
['PYTHON', 'GO', 'java']
>>l[0:2] = ["python", "go"]
>>l
['python', 'go', 'java']

查询元素

index(x) :方法用来查找某个元素在列表中出现的位置(也就是索引),如果该元素不存在,则会导致 ValueError 错误

>>l
['python', 'go', 'java']
>>l.index("python")
0
>>l.index("python1")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ValueError: 'python1' is not in list

count() :用来统计某个元素在列表中出现的次数

>>l
['python', 'go', 'java']
>>l.count("PYTHON")
0
>>l.count("python")
1

其他操作

sort:对列表中的元素进行排序

>>l
['go', 'java', 'python']
>>l.sort(reverse=True)
>>l
['python', 'java', 'go']
>>l.sort()
>>l
['go', 'java', 'python']

reverse: 反转元素

>>l = [1,2,3,4,5]
>>l.reverse()
>>l
[5, 4, 3, 2, 1]

copy: 返回列表的一个浅拷贝,等价于 a[:]

>>l
[5, 4, 3, 2, 1]
>>a = l.copy()
>>a
[5, 4, 3, 2, 1]

python列表使用场景

1-使用列表实现栈

栈(stack)特点就是后进先出, 使用列表实现是非常容易的,要添加一个元素到堆栈的顶端,使用 append() 。要从堆栈顶部取出一个元素,使用 pop()

stack = []
stack.append(1)
stack.append(2)
stack.append(3)
stack.append(4)
stack.pop()
# 4
stack.pop()
# 3
stack.pop()
# 2
stack.pop()
# 1
# 注意捕捉错误

요소를 제거합니다

remove(x): 값이 x인 첫 번째 항목을 목록에서 제거합니다. 삭제할 값이 없으면 예외가 발생합니다.

from collections import deque
queue = deque(["python", "go", "java"])
queue.append("python")
queue.append("go")
print(queue)
queue.popleft()

queue.popleft()
print(queue)

pop: 목록의 지정된 위치에 있는 요소를 제거하고 반환합니다. 위치가 지정되지 않으면 pop()은 목록의 마지막 요소를 삭제하고 반환합니다

deque(['python', 'go', 'java', 'python', 'go'])
deque(['java', 'python', 'go'])
del: 삭제 작업을 수행하는 데 특별히 사용되는 Python의 키워드입니다. 전체 목록을 삭제할 수 있을 뿐만 아니라 , 목록의 특정 요소를 삭제할 수도 있습니다

a = [x ** 2 for x in range(10)]
b = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]

# 嵌套列表推导式
matrix = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
]
c = [[row[i] for row in matrix] for i in range(4)]
print("a:", a)
print("b:", b)
print("c:", c)

clear(): 목록의 모든 요소를 ​​제거합니다. del a[:]

a: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
b: [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
c: [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
ps와 동일: 여기서 del과의 차이점에 유의하세요. Clear는 지우기, del list_name은 삭제, 메모리도 해제됩니다.

요소 수정

단일 메서드 수정 subscripted

a = 1, 2, 3
print("a", a)
b = (1, 2, 3)
print("b", b)
# 将字符串转换成元组
tup1 = tuple("hello")
print("将字符串转换成元组", tup1)

# 将列表转换成元组
list1 = ['Python', 'Java', 'C++', 'JavaScript']
tup2 = tuple(list1)
print("将列表转换成元组", tup2)

# 将字典转换成元组
dict1 = {'a': 100, 'b': 42, 'c': 9}
tup3 = tuple(dict1)
print("将字典转换成元组", tup3)

# 将区间转换成元组
range1 = range(1, 6)
tup4 = tuple(range1)
print("将区间转换成元组", tup4)
슬라이싱을 통해 데이터 세트를 수정할 수 있습니다
a (1, 2, 3)
b (1, 2, 3)
将字符串转换成元组 ('h', 'e', 'l', 'l', 'o')
将列表转换成元组 ('Python', 'Java', 'C++', 'JavaScript')
将字典转换成元组 ('a', 'b', 'c')
将区间转换成元组 (1, 2, 3, 4, 5)

Query elements

index(x): 이 메소드는 목록에서 요소가 나타나는 위치(즉, 인덱스)를 찾는 데 사용됩니다. 요소가 존재하지 않으면 ValueError가 발생합니다.

a = (1, 2, 3, 4, 5)
# 通过下标
print(a[0])
# 通过切片:a[start : end : step]
print(a[0:4:2])

count(): 요소가 목록에 나타나는 횟수를 계산하는 데 사용됩니다

1
(1, 3)

기타 작업

sort: 목록의 요소 정렬

a = (1, 2, 3, 4, 5)
del a
reverse: 요소 반전

l = (1,2,3,4)
id(l)
# 4497372488
l = l + (5,6)
id(l)
# 4494985832
copy: a[:]

l = [1,2,3,4]
id(l)
# 4499169160
l = l + [5,6]
id(l)
# 4495787016

Python 목록 사용 시나리오

1 - 목록을 사용하여 스택 구현🎜🎜에 해당하는 목록의 얕은 복사본을 반환합니다. 스택(Stack)의 특성은 후입선출(Last In First Out)이며, 리스트를 사용하는 것은 스택의 맨 위에 요소를 추가하려면 append()를 사용하면 됩니다. 스택 상단에서 요소를 팝하려면 인덱스를 지정하지 않고 pop()을 사용하세요. 🎜
list_t = []
print("列表初始化时候大小:", list_t.__sizeof__())
tuple_t = ()
print("元组初始化时候大小:", tuple_t.__sizeof__())
🎜2-큐 구현🎜
列表初始化时候大小: 40
元组初始化时候大小: 24
🎜결과 반환🎜
tuple_t = (1, 2)
print("元组hash值:", hash(tuple_t))
list_t = [1, 2]
print("列表hash值:", hash(list_t))
🎜List comprehension🎜
Traceback (most recent call last):
  File "/Users/linjian/MonitorCenter/MonitorCenter/apps/t6.py", line 4, in <module>
    print("列表hash值:", hash(list_t))
TypeError: unhashable type: 'list'
元组hash值: 3713081631934410656
🎜Return🎜
#   初始化一个相同元素的列表和元组使用情况
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)'

100000000 loops, best of 3: 0.0103 usec per loop
(djangoDemo)  MonitorCenter % python -m timeit 'x=[1,2,3,4,5,6]'
10000000 loops, best of 3: 0.0514 usec per loop


#  元组和列表索引操作对比
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]'
10000000 loops, best of 3: 0.0267 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]'
10000000 loops, best of 3: 0.0265 usec per loop
🎜Tuple🎜🎜튜플은 정적이고 고정된 크기이며 요소를 추가, 수정 또는 삭제할 수 없습니다🎜 🎜🎜튜플 만들기🎜 🎜아아아아 🎜반환 결과🎜
(djangoDemo) MonitorCenter % python -m timeit 'x=list()'                
10000000 loops, best of 3: 0.087 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x=[]'    
100000000 loops, best of 3: 0.0177 usec per loop
🎜🎜액세스 요소🎜🎜
(djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x*=3'
10000000 loops, best of 3: 0.0903 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x = x * 3'
10000000 loops, best of 3: 0.104 usec per loop
🎜반환 결과🎜
list_1 = [1, 2, 3, 4]
list_2 = [1, 2, 3, 4]
list_3 = [1, 2, 3, 4]
list_4 = [1, 2, 3, 4]

for idx, item in enumerate(list_1):
    del item

for idx, item in enumerate(list_2):
    list_2.remove(item)

for idx, item in enumerate(list_3[:]):
    list_3.remove(item)

for idx, item in enumerate(list_4):
    list_4.pop(idx)

print("list_1", list_1)
print("list_2", list_2)
print("list_3", list_3)
print("list_4", list_4)
🎜Delete🎜
list_1 [1, 2, 3, 4]
list_2 [2, 4]
list_3 []
list_4 [2, 4]
🎜튜플과 리스트의 차이점🎜🎜튜플은 정적, 리스트는 동적🎜🎜튜플 수정 🎜
give next element: 0
0 ---> 1
1      2
2      3
3      4
give next element: 1
0      2
1 ---> 3
2      4
give next element: 2
0      2
1      4
🎜리스트 수정 🎜rrreee🎜할 수 있어요 위에서는 튜플을 변경할 수 없다는 점을 강조합니다. 여기서는 많은 초보자가 l = l + (5,6)을 이해하는 데 어려움을 겪는다는 점을 강조합니다. 그러면 튜플을 수정할 수 없다는 뜻이 아닌가요? 여기? 여기서 실행할 수는 있지만 이때 l은 원래 l이 아님을 기억하세요. id로 쿼리할 수 있습니다(또는 l[0] = -1을 실행하면 오류가 보고됩니다.) ) 🎜🎜여기서 몇 가지 더 말씀드리겠습니다. 여기서 정적 및 동적은 목록 작업(추가, 삭제, 수정)을 수행할 수 있는 목록입니다. 일반적인 작업 동작에서는 해당 메모리 주소가 변경되지 않습니다. id) 이것은 구현과 관련이 있지만 튜플이 변경되므로 새 튜플은 원래의 튜플과 다릅니다. 일반적으로 누군가(면접관이나 개발자는 조심하지 않음)에게 = ([1)을 묻습니다. ,2], 3, 4), a[0].append(3)를 수행할 수 있는데 id(a)가 변경되지 않은 이유는 아래 첨자 0이 있는 요소가 목록이고 목록을 수정할 수 있기 때문입니다. 🎜🎜목록에는 더 많은 메모리가 필요하고, 튜플에는 더 적은 메모리가 필요합니다🎜rrreee🎜결과 반환🎜
列表初始化时候大小: 40
元组初始化时候大小: 24

 看到结果有没有发现列表比元组大18字节,那么问题来了:这18字节是怎么来的?这是由于列表是动态的,它需要存储指针来指向对应的元素(占用 8 个字节)。另外,由于列表中元素可变,所以需要额外存储已经分配的长度大小(占用 8 个字节),这样才能实时追踪列表空间的使用情况。但是对于元组,情况就不同了,元组长度大小固定,且存储元素不可变,所以存储空间也是固定的。

列表不可被hash,元组可以被hash

tuple_t = (1, 2)
print("元组hash值:", hash(tuple_t))
list_t = [1, 2]
print("列表hash值:", hash(list_t))

执行结果

Traceback (most recent call last):
  File "/Users/linjian/MonitorCenter/MonitorCenter/apps/t6.py", line 4, in <module>
    print("列表hash值:", hash(list_t))
TypeError: unhashable type: 'list'
元组hash值: 3713081631934410656

从上面的结果可以发现元组是可以被hash,但列表却是不可以。如果基础扎实的应该会反应过来,python中hash需要满足是不可变类型的数据结构(字符串str、元组tuple、对象集objects)

执行效率

#   初始化一个相同元素的列表和元组使用情况
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)'

100000000 loops, best of 3: 0.0103 usec per loop
(djangoDemo)  MonitorCenter % python -m timeit 'x=[1,2,3,4,5,6]'
10000000 loops, best of 3: 0.0514 usec per loop


#  元组和列表索引操作对比
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]'
10000000 loops, best of 3: 0.0267 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x=(1,2,3,4,5,6)' 'y=x[3]'
10000000 loops, best of 3: 0.0265 usec per loop

 上面的运行结果显示: 元组初始化远快于列表  ,大概有五倍的差距,但是索引操作的时候速度没有多大差距

截止目前为止,我们可以简单总结列表和元组的区别有如下:

  1. 元组使用tuple()或()初始化,列表使用list()或[]初始化
  2. 元组是静态,而列表是动态
  3. 列表需要更多内存,元组需要更少内存
  4. 列表不可被hash,元组可以被hash
  5. 元组初始化效率高于列表,但索引操作没有多大差距

元组和列表使用场景

再说使用场景前先讲一下,在python后台,对静态数据做一些资源缓存,通常因为垃圾回收机制的存在,一些变量不使用,python就会回收他们所占的内存,但是对于一些静态变量(比如说元组),当他们占用不大时候(长度1~20的元组),python会暂时缓存这部分内存,这样下次就可以不再向操作系统发出请求,分配内存资源,而是直接使用用缓存中之前的内存空间,这样大大加快了程序的运行速度。所以一般有时候数据量不大,我经常使用元组替代列表。到目前为止我们可以简单的总结出场景可以如下所示:

  1. 如果数据不可变,我们就可以考虑使用元组,比如说性别类型,返回出去的城市信息等等
  2. 如果数据可变,我们就考虑使用列表,比如说用户当天访问的网页等等

拓展知识

创建空的列表,是使用list()效率好还是[]?

(djangoDemo) MonitorCenter % python -m timeit 'x=list()'                
10000000 loops, best of 3: 0.087 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x=[]'    
100000000 loops, best of 3: 0.0177 usec per loop

通过上面的测试可以知道是[]快。list()函数调用,python中函数调用会创建stack并且会进行参数检查,[]是一个内置C函数,可以直接调用,因此效率更高。

执行相乘操作时候,是 *= 效率好, 还是*? 

(djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x*=3'
10000000 loops, best of 3: 0.0903 usec per loop
(djangoDemo) MonitorCenter % python -m timeit 'x = [1,2,3]' 'x = x * 3'
10000000 loops, best of 3: 0.104 usec per loop

从结果可以看出是*效率会低点。*= 中会预分配,不足的时候扩容,但是* 会按照每次的量进行分配大小

为什么输出是这样的?

list_1 = [1, 2, 3, 4]
list_2 = [1, 2, 3, 4]
list_3 = [1, 2, 3, 4]
list_4 = [1, 2, 3, 4]

for idx, item in enumerate(list_1):
    del item

for idx, item in enumerate(list_2):
    list_2.remove(item)

for idx, item in enumerate(list_3[:]):
    list_3.remove(item)

for idx, item in enumerate(list_4):
    list_4.pop(idx)

print("list_1", list_1)
print("list_2", list_2)
print("list_3", list_3)
print("list_4", list_4)

结果

list_1 [1, 2, 3, 4]
list_2 [2, 4]
list_3 []
list_4 [2, 4]

 list_2为什么输出是[2,4]? 因为在第一次删除后,list_2变成了 [2,3,4], 然后在删除轮循到到第二个数据也就是3(大部分都以为是2,但是2从原来的下表2变为1),可以参看下面的

give next element: 0
0 ---> 1
1      2
2      3
3      4
give next element: 1
0      2
1 ---> 3
2      4
give next element: 2
0      2
1      4

list_3 为什么是[], 还记得之前我们说copy时候,copy等于[:](浅拷贝),所以轮询的和删除的不是同一内存的数据。

list_4可以结合list_2思考,因为第一次删除,第二次删除是下标2,但是数据变了,下标2的数据不是原来的2,而是3

推荐学习:python教程

위 내용은 Python 목록 및 튜플에 대한 자세한 설명(예제와 함께 자세한 설명)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제