Python Language
Список
Поиск…
Вступление
Список Python - это общая структура данных, широко используемая в программах Python. Они находятся на других языках, часто называемых динамическими массивами . Они оба изменяемы и имеют тип данных последовательности, который позволяет их индексировать и нарезать . Список может содержать различные типы объектов, включая другие объекты списка.
Синтаксис
- [значение, значение, ...]
- список ([итерация])
замечания
list
является конкретным типом итерации, но он не единственный, который существует в Python. Иногда лучше использовать set
, tuple
или dictionary
list
- это имя, указанное в Python для динамических массивов (подобно vector<void*>
из C ++ или Java ArrayList<Object>
). Это не связанный список.
Доступ к элементам осуществляется в постоянное время и очень быстро. Добавление элементов в конец списка является амортизированным постоянным временем, но время от времени оно может включать в себя распределение и копирование всего list
.
Перечисления списков относятся к спискам.
Доступ к значениям списка
Списки Python ноль-индексируются и действуют как массивы на других языках.
lst = [1, 2, 3, 4]
lst[0] # 1
lst[1] # 2
Попытка доступа к индексу за пределами списка приведет к созданию IndexError
.
lst[4] # IndexError: list index out of range
Отрицательные индексы интерпретируются как считанные с конца списка.
lst[-1] # 4
lst[-2] # 3
lst[-5] # IndexError: list index out of range
Это функционально эквивалентно
lst[len(lst)-1] # 4
Списки позволяют использовать нотацию среза как lst[start:end:step]
. Вывод нотации среза - это новый список, содержащий элементы от start
индекса до end-1
. Если параметры опущены, start
умолчанию начало списка, от end
до конца списка и step
1:
lst[1:] # [2, 3, 4]
lst[:3] # [1, 2, 3]
lst[::2] # [1, 3]
lst[::-1] # [4, 3, 2, 1]
lst[-1:0:-1] # [4, 3, 2]
lst[5:8] # [] since starting index is greater than length of lst, returns empty list
lst[1:10] # [2, 3, 4] same as omitting ending index
Имея это в виду, вы можете распечатать отмененную версию списка, позвонив
lst[::-1] # [4, 3, 2, 1]
При использовании длины шагов отрицательных сумм начальный индекс должен быть больше, чем конечный индекс, иначе результат будет пустым.
lst[3:1:-1] # [4, 3]
Использование отрицательных индексов шагов эквивалентно следующему коду:
reversed(lst)[0:2] # 0 = 1 -1
# 2 = 3 -1
Используемые индексы на 1 меньше, чем те, которые используются при отрицательной индексации, и меняются на противоположные.
Расширенный нарезка
Когда списки __getitem__()
метод __getitem__()
объекта списка с объектом slice
. Python имеет встроенный метод среза для создания объектов среза. Мы можем использовать это для хранения фрагмента и повторного использования позже,
data = 'chandan purohit 22 2000' #assuming data fields of fixed length
name_slice = slice(0,19)
age_slice = slice(19,21)
salary_slice = slice(22,None)
#now we can have more readable slices
print(data[name_slice]) #chandan purohit
print(data[age_slice]) #'22'
print(data[salary_slice]) #'2000'
Это может быть очень __getitem__
предоставляя функции среза для наших объектов, переопределяя __getitem__
в нашем классе.
Методы списка и поддерживаемые операторы
Начиная с данного списка a
:
a = [1, 2, 3, 4, 5]
append(value)
- добавляет новый элемент в конец списка.# Append values 6, 7, and 7 to the list a.append(6) a.append(7) a.append(7) # a: [1, 2, 3, 4, 5, 6, 7, 7] # Append another list b = [8, 9] a.append(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]] # Append an element of a different type, as list elements do not need to have the same type my_string = "hello world" a.append(my_string) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9], "hello world"]
Обратите внимание, что метод
append()
добавляет только один новый элемент в конец списка. Если вы добавляете список в другой список, список, который вы добавляете, становится единственным элементом в конце первого списка.# Appending a list to another list a = [1, 2, 3, 4, 5, 6, 7, 7] b = [8, 9] a.append(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, [8, 9]] a[8] # Returns: [8,9]
extend(enumerable)
- расширяет список, добавляя элементы из другого перечисляемого.a = [1, 2, 3, 4, 5, 6, 7, 7] b = [8, 9, 10] # Extend list by appending all elements from b a.extend(b) # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] # Extend list with elements from a non-list enumerable: a.extend(range(3)) # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 0, 1, 2]
Списки также могут быть объединены с оператором
+
. Обратите внимание, что это не изменяет ни один из исходных списков:a = [1, 2, 3, 4, 5, 6] + [7, 7] + b # a: [1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
index(value, [startIndex])
- получает индекс первого вхождения входного значения. Если входное значение отсутствует в списке, возникает исключениеValueError
. Если предоставляется второй аргумент, поиск начинается с указанного индекса.a.index(7) # Returns: 6 a.index(49) # ValueError, because 49 is not in a. a.index(7, 7) # Returns: 7 a.index(7, 8) # ValueError, because there is no 7 starting at index 8
insert(index, value)
- вставляетvalue
непосредственно перед указаннымindex
. Таким образом, после вставки новый элемент занимаетindex
позиции.a.insert(0, 0) # insert 0 at position 0 a.insert(2, 5) # insert 5 at position 2 # a: [0, 1, 5, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10]
pop([index])
- удаляет и возвращает элемент поindex
. Без аргумента он удаляет и возвращает последний элемент списка.a.pop(2) # Returns: 5 # a: [0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10] a.pop(8) # Returns: 7 # a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # With no argument: a.pop() # Returns: 10 # a: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
remove(value)
- удаляет первое вхождение указанного значения. Если предоставленное значение не может быть найдено, повышается значениеValueError
.a.remove(0) a.remove(9) # a: [1, 2, 3, 4, 5, 6, 7, 8] a.remove(10) # ValueError, because 10 is not in a
reverse()
- отменяет список на месте и возвращаетNone
.a.reverse() # a: [8, 7, 6, 5, 4, 3, 2, 1]
Существуют также другие способы обращения вспять списка .
count(value)
- подсчитывает количество вхождений некоторого значения в списке.a.count(7) # Returns: 2
sort()
- сортирует список в числовом и лексикографическом порядке и возвращаетNone
.a.sort() # a = [1, 2, 3, 4, 5, 6, 7, 8] # Sorts the list in numerical order
Списки также могут быть отменены при сортировке с использованием флага
reverse=True
в методеsort()
.a.sort(reverse=True) # a = [8, 7, 6, 5, 4, 3, 2, 1]
Если вы хотите сортировать по атрибутам элементов, вы можете использовать
key
аргументkey
слова:import datetime class Person(object): def __init__(self, name, birthday, height): self.name = name self.birthday = birthday self.height = height def __repr__(self): return self.name l = [Person("John Cena", datetime.date(1992, 9, 12), 175), Person("Chuck Norris", datetime.date(1990, 8, 28), 180), Person("Jon Skeet", datetime.date(1991, 7, 6), 185)] l.sort(key=lambda item: item.name) # l: [Chuck Norris, John Cena, Jon Skeet] l.sort(key=lambda item: item.birthday) # l: [Chuck Norris, Jon Skeet, John Cena] l.sort(key=lambda item: item.height) # l: [John Cena, Chuck Norris, Jon Skeet]
В случае списка dicts понятие одно и то же:
import datetime l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'height': 175}, {'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'height': 180}, {'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'height': 185}] l.sort(key=lambda item: item['name']) # l: [Chuck Norris, John Cena, Jon Skeet] l.sort(key=lambda item: item['birthday']) # l: [Chuck Norris, Jon Skeet, John Cena] l.sort(key=lambda item: item['height']) # l: [John Cena, Chuck Norris, Jon Skeet]
Сортировать по sub dict:
import datetime l = [{'name':'John Cena', 'birthday': datetime.date(1992, 9, 12),'size': {'height': 175, 'weight': 100}}, {'name': 'Chuck Norris', 'birthday': datetime.date(1990, 8, 28),'size' : {'height': 180, 'weight': 90}}, {'name': 'Jon Skeet', 'birthday': datetime.date(1991, 7, 6), 'size': {'height': 185, 'weight': 110}}] l.sort(key=lambda item: item['size']['height']) # l: [John Cena, Chuck Norris, Jon Skeet]
Лучший способ сортировки с помощью attrgetter
и itemgetter
Списки также могут быть отсортированы с помощью attrgetter
и itemgetter
из модуля оператора. Это может улучшить читаемость и повторное использование. Вот несколько примеров,
from operator import itemgetter,attrgetter
people = [{'name':'chandan','age':20,'salary':2000},
{'name':'chetan','age':18,'salary':5000},
{'name':'guru','age':30,'salary':3000}]
by_age = itemgetter('age')
by_salary = itemgetter('salary')
people.sort(key=by_age) #in-place sorting by age
people.sort(key=by_salary) #in-place sorting by salary
itemgetter
также может быть присвоен индекс. Это полезно, если вы хотите сортировать по индексам кортежа.
list_of_tuples = [(1,2), (3,4), (5,0)]
list_of_tuples.sort(key=itemgetter(1))
print(list_of_tuples) #[(5, 0), (1, 2), (3, 4)]
Используйте attrgetter
если вы хотите сортировать по атрибутам объекта,
persons = [Person("John Cena", datetime.date(1992, 9, 12), 175),
Person("Chuck Norris", datetime.date(1990, 8, 28), 180),
Person("Jon Skeet", datetime.date(1991, 7, 6), 185)] #reusing Person class from above example
person.sort(key=attrgetter('name')) #sort by name
by_birthday = attrgetter('birthday')
person.sort(key=by_birthday) #sort by birthday
clear()
- удаляет все элементы из спискаa.clear() # a = []
Репликация - умножение существующего списка на целое число приведет к созданию большего списка, состоящего из множества копий оригинала. Это может быть полезно, например, для инициализации списка:
b = ["blah"] * 3 # b = ["blah", "blah", "blah"] b = [1, 3, 5] * 5 # [1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5]
Позаботьтесь об этом, если ваш список содержит ссылки на объекты (например, список списков), см. « Общие ошибки» - умножение списка и общие ссылки .
Удаление элемента - можно удалить несколько элементов в списке, используя ключевое слово
del
и фрагмент:a = list(range(10)) del a[::2] # a = [1, 3, 5, 7, 9] del a[-1] # a = [1, 3, 5, 7] del a[:] # a = []
копирование
Назначение по умолчанию «=» присваивает ссылку исходного списка на новое имя. То есть исходное имя и новое имя указывают на один и тот же объект списка. Изменения, внесенные через любой из них, будут отражены в другом. Это часто не то, что вы намеревались.
b = a a.append(6) # b: [1, 2, 3, 4, 5, 6]
Если вы хотите создать копию списка, у вас есть варианты ниже.
Вы можете отрезать его:
new_list = old_list[:]
Вы можете использовать встроенную функцию list ():
new_list = list(old_list)
Вы можете использовать generic copy.copy ():
import copy new_list = copy.copy(old_list) #inserts references to the objects found in the original.
Это немного медленнее, чем list (), потому что сначала нужно выяснить тип данных old_list.
Если список содержит объекты и вы хотите их скопировать, используйте общий copy.deepcopy ():
import copy new_list = copy.deepcopy(old_list) #inserts copies of the objects found in the original.
Очевидно, самый медленный и самый необходимый для памяти способ, но иногда неизбежный.
copy()
- возвращает неполную копию списка
aa = a.copy()
# aa = [1, 2, 3, 4, 5]
Длина списка
Используйте len()
чтобы получить одномерную длину списка.
len(['one', 'two']) # returns 2
len(['one', [2, 3], 'four']) # returns 3, not 4
len()
также работает с строками, словарями и другими структурами данных, подобными спискам.
Обратите внимание: len()
- это встроенная функция, а не метод объекта списка.
Также обратите внимание, что стоимость len()
равна O(1)
, то есть потребуется столько же времени, чтобы получить длину списка независимо от его длины.
Итерирование по списку
Python поддерживает использование цикла for
непосредственно в списке:
my_list = ['foo', 'bar', 'baz']
for item in my_list:
print(item)
# Output: foo
# Output: bar
# Output: baz
Вы также можете получить позицию каждого элемента одновременно:
for (index, item) in enumerate(my_list):
print('The item in position {} is: {}'.format(index, item))
# Output: The item in position 0 is: foo
# Output: The item in position 1 is: bar
# Output: The item in position 2 is: baz
Другой способ итерации списка на основе значения индекса:
for i in range(0,len(my_list)):
print(my_list[i])
#output:
>>>
foo
bar
baz
Обратите внимание, что изменение элементов в списке при повторном запуске может иметь неожиданные результаты:
for item in my_list:
if item == 'foo':
del my_list[0]
print(item)
# Output: foo
# Output: baz
В этом последнем примере мы удалили первый элемент на первой итерации, но это привело к тому, что bar
был пропущен.
Проверка наличия элемента в списке
Python упрощает проверку наличия элемента в списке. Просто используйте оператор in
.
lst = ['test', 'twest', 'tweast', 'treast']
'test' in lst
# Out: True
'toast' in lst
# Out: False
Примечание: оператор
in
на множестве асимптотически быстрее, чем в списках. Если вам нужно использовать его много раз в потенциально больших списках, вы можете захотеть преобразовать свойlist
вset
и проверить наличие элементов вset
.
slst = set(lst)
'test' in slst
# Out: True
Элементы реверсивного списка
Вы можете использовать reversed
функцию, которая возвращает итератор в обратный список:
In [3]: rev = reversed(numbers)
In [4]: rev
Out[4]: [9, 8, 7, 6, 5, 4, 3, 2, 1]
Обратите внимание, что список «числа» остается неизменным для этой операции и остается в том же порядке, что и был изначально.
Вы можете использовать reverse
метод .
Вы также можете отменить список (на самом деле получить копию, исходный список не затронут), используя синтаксис разрезания, установив третий аргумент (шаг) как -1:
In [1]: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
In [2]: numbers[::-1]
Out[2]: [9, 8, 7, 6, 5, 4, 3, 2, 1]
Проверка наличия пустого списка
Пустота списка связана с логическим False
, поэтому вам не нужно проверять len(lst) == 0
, но только lst
или not lst
lst = []
if not lst:
print("list is empty")
# Output: list is empty
Списки конкатенации и объединения
Самый простой способ объединить
list1
иlist2
:merged = list1 + list2
zip
возвращает список кортежей , где i-й кортеж содержит i-й элемент из каждой из последовательностей аргументов или итераций:alist = ['a1', 'a2', 'a3'] blist = ['b1', 'b2', 'b3'] for a, b in zip(alist, blist): print(a, b) # Output: # a1 b1 # a2 b2 # a3 b3
Если списки имеют разную длину, тогда результат будет содержать только столько элементов, сколько кратчайший:
alist = ['a1', 'a2', 'a3'] blist = ['b1', 'b2', 'b3', 'b4'] for a, b in zip(alist, blist): print(a, b) # Output: # a1 b1 # a2 b2 # a3 b3 alist = [] len(list(zip(alist, blist))) # Output: # 0
Для заполнения списков неравной длины до самой длинной с помощью
None
s используйтеitertools.zip_longest
(itertools.izip_longest
в Python 2)alist = ['a1', 'a2', 'a3'] blist = ['b1'] clist = ['c1', 'c2', 'c3', 'c4'] for a,b,c in itertools.zip_longest(alist, blist, clist): print(a, b, c) # Output: # a1 b1 c1 # a2 None c2 # a3 None c3 # None None c4
Вставка в определенные значения индекса:
alist = [123, 'xyz', 'zara', 'abc'] alist.insert(3, [2009]) print("Final List :", alist)
Выход:
Final List : [123, 'xyz', 'zara', 2009, 'abc']
Каждый и все
Вы можете использовать all()
чтобы определить, соответствуют ли все значения в итерабельной True
nums = [1, 1, 0, 1]
all(nums)
# False
chars = ['a', 'b', 'c', 'd']
all(chars)
# True
Аналогично, any()
определяет, имеет ли одно или несколько значений в итерабельной значение True
nums = [1, 1, 0, 1]
any(nums)
# True
vals = [None, None, None, False]
any(vals)
# False
Хотя в этом примере используется список, важно отметить, что эти встроенные работы работают с любым итерабельным, включая генераторы.
vals = [1, 2, 3, 4]
any(val > 12 for val in vals)
# False
any((val * 2) > 6 for val in vals)
# True
Удалить повторяющиеся значения в списке
Удаление повторяющихся значений в списке может быть выполнено путем преобразования списка в set
(это неупорядоченный набор отдельных объектов). Если структура данных list
необходима, то набор можно преобразовать обратно в список, используя list()
функций list()
:
names = ["aixk", "duke", "edik", "tofp", "duke"]
list(set(names))
# Out: ['duke', 'tofp', 'aixk', 'edik']
Обратите внимание, что путем преобразования списка в набор исходное упорядочение теряется.
Для сохранения порядка списка можно использовать OrderedDict
import collections
>>> collections.OrderedDict.fromkeys(names).keys()
# Out: ['aixk', 'duke', 'edik', 'tofp']
Доступ к значениям во вложенном списке
Начиная с трехмерного списка:
alist = [[[1,2],[3,4]], [[5,6,7],[8,9,10], [12, 13, 14]]]
Доступ к элементам в списке:
print(alist[0][0][1])
#2
#Accesses second element in the first list in the first list
print(alist[1][1][2])
#10
#Accesses the third element in the second list in the second list
Выполнение операций поддержки:
alist[0][0].append(11)
print(alist[0][0][2])
#11
#Appends 11 to the end of the first list in the first list
Использование вложенных циклов для печати списка:
for row in alist: #One way to loop through nested lists
for col in row:
print(col)
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#[12, 13, 14]
Обратите внимание, что эта операция может использоваться в понимании списка или даже в качестве генератора для повышения эффективности, например:
[col for row in alist for col in row]
#[[1, 2, 11], [3, 4], [5, 6, 7], [8, 9, 10], [12, 13, 14]]
Не все элементы во внешних списках должны быть самими списками:
alist[1].insert(2, 15)
#Inserts 15 into the third position in the second list
Другой способ использования вложенных циклов. Другой способ лучше, но я должен был использовать это иногда:
for row in range(len(alist)): #A less Pythonic way to loop through lists
for col in range(len(alist[row])):
print(alist[row][col])
#[1, 2, 11]
#[3, 4]
#[5, 6, 7]
#[8, 9, 10]
#15
#[12, 13, 14]
Использование срезов во вложенном списке:
print(alist[1][1:])
#[[8, 9, 10], 15, [12, 13, 14]]
#Slices still work
Окончательный список:
print(alist)
#[[[1, 2, 11], [3, 4]], [[5, 6, 7], [8, 9, 10], 15, [12, 13, 14]]]
Сравнение списков
Можно сравнивать списки и другие последовательности с лексикографическим использованием операторов сравнения. Оба операнда должны быть одного типа.
[1, 10, 100] < [2, 10, 100]
# True, because 1 < 2
[1, 10, 100] < [1, 10, 100]
# False, because the lists are equal
[1, 10, 100] <= [1, 10, 100]
# True, because the lists are equal
[1, 10, 100] < [1, 10, 101]
# True, because 100 < 101
[1, 10, 100] < [0, 10, 100]
# False, because 0 < 1
Если один из списков содержится в начале другого, выигрывает самый короткий список.
[1, 10] < [1, 10, 100]
# True
Инициализация списка для фиксированного количества элементов
Для неизменяемых элементов (например, None
, строковые литералы и т. Д.):
my_list = [None] * 10
my_list = ['test'] * 10
Для изменяемых элементов одна и та же конструкция приведет к тому, что все элементы списка относятся к одному и тому же объекту, например, для набора:
>>> my_list=[{1}] * 10
>>> print(my_list)
[{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}]
>>> my_list[0].add(2)
>>> print(my_list)
[{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}]
Вместо этого, чтобы инициализировать список с фиксированным числом различных изменяемых объектов, используйте:
my_list=[{1} for _ in range(10)]