Списки вредных профессий №1 и 2
- Главная
- Глоссарий
- Списки вредных профессий №1 и 2
Списки работ, производств, профессий, должностей, специальностей, учреждений (организаций), дающих право на досрочную страховую пенсию.
Разъяснения, как определять специальный трудовой стаж и применять Списки, содержатся в постановлении Правительства РФ от 16.07.2014 №665.
Список №1 определяет профессии, способные причинить тяжкий вред здоровью. Сюда относятся в т. ч. такие направления трудовой деятельности:
- разработка горных пород
- обогащение и обжиг руды
- производство черных и цветных металлов
- специалисты, задействованные в коксохимической отрасли
- сотрудники, связанные с генераторными газами и химвеществами
- задействованные на производстве боеприпасов и взрывоопасных веществ
- нефтегазовая добыча и переработка
- специалисты по металлообработке
- изготовители стройматериалов
- работники, занятые изготовлением продукции из стекла, фарфора, искусственных волокон
- работники целлюлозно-бумажных комбинатов
- представители автотранспортных предприятий
- лица, занимающиеся полиграфией
- фармацевты
- работа с радиоактивными веществами, специалисты в области атомной энергетики и промышленности.
Для оформления досрочной пенсии по списку №1:
- мужчины должны отработать на вредном предприятии не менее 10 лет (уходят на пенсию в 50 лет)
- женщины должны отработать на вредном предприятии не менее 7 лет и 6 месяцев (уходят на пенсию в 45 лет).
Список №2 включает менее вредные профессии, но продолжительная занятость в этой сфере может негативно отразиться на состоянии здоровья. Сюда относятся:
- должности, связанные с переработкой полезных ископаемых
- металлургия
- газоэлектросварщики
- работники железнодорожного транспорта
- лица, занятые на предприятиях пищевой отрасли
- сотрудники здравоохранения
- торфодобыча
- служащие агрохимических комплексов
- предприятия связи
- электротехники и специалисты, занимающиеся ремонтом электротехнического оборудования
- строительные специальности.
Для оформления досрочной пенсии по списку №2:
- мужчины должны отработать на вредном предприятии не менее 12 с половиной лет (уходят на пенсию в 55 лет)
- женщины должны отработать на вредном предприятии не менее 10 лет (уходят на пенсию в 50 лет).
382
Информация актуальна на 22.11.2019 г.
…
Строки, кортежи, списки — Основы Python
В первой главе мы познакомились с таким типом данных, как строка (str
). Мы умеем складывать строки, умножать их на число и даже сравнивать между собой.
Если рассмотреть строку детальнее, то она состоит из символов, каждый из которых стоит на своём месте. Другими словами, строка — упорядоченная последовательность (коллекция) символов.
Слово «коллекция» в Python применяется не только к строкам. Коллекциями в Python также называют типы данных, в которых можно хранить сразу несколько значений.
В упорядоченных коллекциях, к которым относится строка, каждое значение автоматически имеет свой номер — индекс. Индексация в коллекциях Python начинается со значения 0. При этом пробел, запятая, управляющие символы \n
, \t
и прочие тоже получают свой индекс в строке. Для доступа к определённому символу строки по индексу нужно указать его в квадратных скобках сразу после имени переменной.
Давайте создадим программу, которая выводит первый символ строки, введённой пользователем:
text = input() print(text[0])
Если пользователь введёт пустую строку, то наша программа выдаст ошибку:
IndexError: string index out of range
В пустой строке нет символов, и программа вышла за пределы строки. Таким образом, нельзя получить значение по индексу, который за пределами строки. Перед обращением к символу строки по индексу можно проверять, не выходит ли он за пределы строки, используя известную нам функцию len
следующим образом:
text = input("Введите строку: ") i = int(input("Введите индекс символа: ")) if i < len(text): print(text[i]) else: print("Индекс выходит за пределы строки")
Давайте подумаем, как можно взять последний символ строки? Для этого нам потребуется воспользоваться функцией len
:
text = input() print(text[len(text) - 1])
Однако в Python можно упростить эту запись, убрав из неё функцию len
. И тогда в качестве индекса просто будет использоваться отрицательное число:
text = input() print(text[-1])
Таким образом, последний символ имеет индекс -1, предпоследний -2 и т. д.
Так как строка — упорядоченная коллекция, то можно пройти по этой коллекции в цикле, указав в качестве индекса итерируемую переменную цикла. Например, вывести на строке каждый символ введённой пользователем строки:
text = input() for i in range(len(text)): print(text[i])
Существует и другой способ пройти по символам строки в цикле. Если не требуется на каждой итерации цикла знать индекс текущего символа, то цикл можно оформить следующим образом:
text = input() for letter in text: print(letter)
При такой записи цикла программа проходит не по индексам строки, а непосредственно по её символам. Так, переменная letter
на каждой итерации цикла принимает значение очередного символа строки text
.
Если требуется совместить проход непосредственно по символам строки с определением индекса итерации, то можно воспользоваться функцией enumerate
.
text = input() for i, letter in enumerate(text): print(f"{i}. {letter}")
Для строк в Python существует ещё одна полезная операция — срез (slice
).
Срез позволяет взять часть строки, указав начальный и конечный индексы (конечный индекс не включается в диапазон). Также можно указать шаг, с которым срез будет взят (по умолчанию шаг 1). Например, в одной из прошлых глав мы аналогичным образом использовали функцию range
Кроме того, в срезах можно использовать отрицательную индексацию. А если срез выходит за пределы строки, то программа не упадёт с ошибкой, а просто вернёт существующую часть строки.
Следующий пример показывает возможные варианты использования срезов:
text = "Привет, мир!" print(text[8:11]) print(text[:6]) print(text[8:]) print(text[:]) print(text[::2])
Обратите внимание: строка является неизменяемой коллекцией. Это означает, что изменить отдельный символ строки нельзя.
Например, попытаемся в следующей программе изменить значение одного из символов строки:
word = "мир" word[0] = "п"
Программа выдаст ошибку:
TypeError: 'str' object does not support item assignment
Мы уже знаем, что взаимодействовать с переменными в Python можно с помощью операций и функций. Рассмотрим ещё один способ взаимодействия — методы.
Методы похожи на функции, но вызываются не сами по себе, а для конкретной переменной. Для каждого типа данных есть свой набор методов. Чтобы вызвать метод, его нужно указать через точку после имени переменной. В круглых скобках после имени метода дополнительно можно обозначить аргументы (параметры) вызываемого метода, как это делаем с функциями.
Например, у строк есть метод islower(), который проверяет, что в строке не встречаются большие буквы, и возвращает в таком случае значение True, иначе — False:
print("а".islower()) print("A". islower())
True False
В следующей таблице перечислены часто используемые методы строк и примеры их работы. Важный момент: методы строк не меняют исходную строку, а возвращают новое значение, которое можно сохранить в переменной.
str.capitalize()
Метод | str.capitalize() |
Описание | Возвращает копию строки, у которой первая буква заглавная, а остальные приведены к строчным |
Пример | s = «hello, World!» s.capitalize() |
Результат | Hello, world! |
str.count(sub)
Метод | str.count(sub) |
Описание | Возвращает количество неперекрывающихся вхождений подстроки sub . К примеру, если искать в строке «ААААА» неперекрывающиеся значения «АА», то первое вхождение будет «AAAAA». Второе — «AAAAA». Больше неперекрывающихся вхождений нет. Так, поиск последующих вхождений подстроки происходит с индекса, который следует за последним найденным вхождением |
Пример | s = «Hello, world!» s. count(«l») |
Результат | 3 |
str.endswith(suffix)
Метод | str.endswith(suffix) |
Описание | Возвращает True, если строка оканчивается на подстроку suffix . Иначе возвращает False. suffix может быть кортежем проверяемых окончаний строки |
Пример | s = «Hello, world!» s.endswith(«world!») |
Результат | True |
str.find(sub)
Метод | str.find(sub) |
Описание | Возвращает индекс первого вхождения подстроки sub . Если подстрока не найдена, то возвращает -1 |
Пример | s = «Hello, world!» s.find(«o») |
Результат | 4 |
str.index(sub)
Метод | str.index(sub) |
Описание | Возвращает индекс первого вхождения подстроки sub . Вызывает исключение ValueError, если подстрока не найдена. Тема ошибок (исключений) будет разбираться на одной из следующих глав |
Пример | s = «Hello, world!» s.index(«o») |
Результат | 4 |
str.isalnum()
Метод | str.isalnum() |
Описание | Возвращает True, если все символы строки являются буквами и цифрами и в строке есть хотя бы один символ. Иначе возвращает False |
Пример | s = «abc123» s.isalnum() |
Результат | True |
str.isalpha()
Метод | str.isalpha() |
Описание | Возвращает True, если все символы строки являются буквами и в строке есть хотя бы один символ. Иначе возвращает False |
Пример | s = «Letters» s.isalpha() |
Результат | True |
str.isdigit()
Метод | str. isdigit() |
Описание | Возвращает True, если все символы строки являются цифрами и в строке есть хотя бы один символ. Иначе возвращает False |
Пример | s = «123» s.isdigit() |
Результат | True |
str.islower()
Метод | str.islower() |
Описание | Возвращает True, если все буквы в строке маленькие и в строке есть хотя бы одна буква. Иначе возвращает False |
Пример | s = «word123» s.islower() |
Результат | True |
str.isupper()
Метод | str.isupper() |
Описание | Возвращает True, если все буквы в строке большие и в строке есть хотя бы одна буква. Иначе возвращает False |
Пример | s = «WORD123» s.isupper() |
Результат | True |
str.join(str_col)
Метод | str. join(str_col) |
Описание | Возвращает строку, полученную конкатенацией (сложением) строк — элементов коллекции str_col (обозначение коллекции с элементами типа данных «строка»). Разделителем является строка, для которой вызван метод |
Пример | a = [«1», «2», «3»] «; «.join(a) |
Результат | «1; 2; 3» |
str.ljust(width, fillchar)
Метод | str.ljust(width, fillchar) |
Описание | Возвращает строку длиной width с выравниванием по левому краю. Строка дополняется справа символами fillchar до требуемой длины. По умолчанию значение fillchar — пробел |
Пример | s = «text» s.ljust(10, «=») |
Результат | «text======» |
str.rstrip(chars)
Метод | str.rstrip(chars) |
Описание | Возвращает строку, у которой в конце удалены символы, встречающиеся в строке chars . Если значение chars не задано, то пробельные символы удаляются |
Пример | s = «stringBCCA» s.rstrip(«ABC») |
Результат | «string» |
str.split(sep)
Метод | str.split(sep) |
Описание | Возвращает список строк по разделителю sep . По умолчанию sep — любое количество пробельных символов |
Пример | s = «one, two, three» s.split(«, «) |
Результат | [«one», «two», «three»] |
str.startswith(prefix)
Метод | str.startswith(prefix) |
Описание | Возвращает True, если строка начинается на подстроку prefix , иначе возвращает False. prefix может быть кортежем проверяемых префиксов строки. Под кортежами подразумевается неизменяемая последовательность элементов |
Пример | s = «Hello, world!» s. startswith(«Hello») |
Результат | True |
str.strip(chars)
Метод | str.strip(chars) |
Описание | Возвращает строку, у которой в начале и в конце удалены символы, встречающиеся в строке chars . Если значение chars не задано, то пробельные символы удаляются |
Пример | s = «abc Hello, world! cba» s.strip(» abc») |
Результат | «Hello, world!» |
str.title()
Метод | str.title() |
Описание | Возвращает строку, в которой каждое отдельное слово начинается с буквы в верхнем регистре, а остальные буквы идут в нижнем |
Пример | s = «hello, world!» s.title() |
Результат | «Hello, World!» |
str.upper()
Метод | str.upper() |
Описание | Возвращает копию строки, у которой все буквы приведены к верхнему регистру |
Пример | s = «Hello, world!» s. upper() |
Результат | «HELLO, WORLD!» |
str.zfill(width)
Метод | str.zfill(width) |
Описание | Возвращает строку, дополненную слева символами «0» до длины width |
Пример | s = «123» s.zfill(5) |
Результат | «00123» |
Рассмотрим ещё одну коллекцию в Python — список (list
). Этот тип данных является упорядоченной коллекцией, которая может в качестве элементов иметь значения любого типа данных.
Один из способов создания списков — перечислить его элементы в квадратных скобках и присвоить это значение переменной, которая и станет в итоге списком в программе:
numbers = [10, 20, 30]
В примере мы создали список, состоящий из трёх элементов — целых чисел. Список может хранить значения любого типа, поэтому можно создать список со следующими элементами:
mixed_list = [10, 20.55, "text"]
Индексация в списках работает так же, как и в строках, — начальный индекс 0. Можно использовать отрицательные индексы, а также доступны срезы:
numbers = [10, 20, 30, 40, 50] print(numbers[0]) print(numbers[-1]) print(numbers[1:3]) print(numbers[::-1])
Результат работы программы:
10 50 [20, 30] [50, 40, 30, 20, 10]
В отличие от строки, список относится к изменяемой коллекции. У списка можно изменить отдельный элемент, добавить новые или удалить существующие. Для изменения существующего элемента нужно указать его в левой части операции присваивания, а в правой указать новое значение этого элемента:
numbers = [10, 20, 50] numbers[2] = 30 print(numbers)
Вывод программы:
[10, 20, 30]
Если требуется добавить элемент в конец списка, то можно использовать метод append().
Например, напишем программу, в которой список последовательно заполняется 10 целочисленными значениями с клавиатуры:
numbers = [] for i in range(10): numbers.append(int(input())) print(numbers)
Вывод программы:
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Для удаления элемента из списка применяется операция del. Нужно указать индекс элемента, который требуется удалить:
numbers = [10, 20, 50] del numbers[-1] print(numbers)
Вывод программы:
[10, 20]
С помощью del
можно удалить несколько элементов списка. Для этого вместо одного элемента указываем срез:
numbers = [1, 2, 3, 4, 5] del numbers[::2] print(numbers)
Вывод программы:
[2, 4]
Полезные методы и функции списков и примеры их работы приведены в следующей таблице.
Операция | Описание | Пример | Результат |
---|---|---|---|
x in s | Возвращает True, если в списке s есть элемент x. Иначе False | 1 in [1, 2, 3] | True |
x not in s | Возвращает False, если в списке s есть элемент x. Иначе True | 4 not in [1, 2, 3] | True |
s + t | Возвращает список, полученный конкатенацией списков s и t | [1, 2] + [3, 4, 5] | [1, 2, 3, 4, 5] |
s * n (n * s) | Возвращает список, полученный дублированием n раз списка s | [1, 2, 3] * 3 | [1, 2, 3, 1, 2, 3, 1, 2, 3] |
len(s) | Возвращает длину списка s | len([1, 2, 3]) | 3 |
min(s) | Возвращает минимальный элемент списка | min([1, 2, 3]) | 1 |
max(s) | Возвращает максимальный элемент списка | max([1, 2, 3]) | 3 |
s. index(x) | Возвращает индекс первого найденного элемента x. Вызывается исключение ValueError, если элемент не найден | [1, 2, 3, 2, 1].index(2) | 1 |
s.count(x) | Возвращает количество элементов x | [1, 1, 1, 2, 3, 1].count(1) | 4 |
s.append(x) | Добавляет элемент x в конец списка | s = [1, 2] s.append(3) print(s) | [1, 2, 3] |
s.clear() | Удаляет все элементы списка | s = [1, 2, 3] s.clear() print(s) | [] |
s.copy() | Возвращает копию списка | [1, 2, 3].copy() | [1, 2, 3] |
s.extend(t) или s += t | Расширяет список s элементами списка t | s = [1, 2, 3] s.extend([4, 5]) print(s) | [1, 2, 3, 4, 5] |
s.insert(i, x) | Вставляет элемент x в список по индексу i | s = [1, 3, 4] s.insert(1, 2) print(s) | [1, 2, 3, 4] |
s.pop(i) | Возвращает и удаляет элемент с индексом i. Если i не указан, то возвращается и удаляется последний элемент | s = [1, 2, 3] x = s.pop() print(x) print(s) | 3 [1, 2] |
s.remove(x) | Удаляет первый элемент со значением x | s = [1, 2, 3, 2, 1] s.remove(2) print(s) | [1, 3, 2, 1] |
s.reverse() | Меняет порядок элементов списка на противоположный (переворачивает список) | s = [1, 2, 3] s.reverse() print(s) | [3, 2, 1] |
s.sort() | Сортирует список по возрастанию, меняя исходный список. Для сортировки по убыванию используется дополнительный аргумент reverse=True | s = [2, 3, 1] s.sort() print(s) | [1, 2, 3] |
sorted(s) | Возвращает отсортированный по возрастанию список, не меняя исходный. Для сортировки по убыванию используется дополнительный аргумент reverse=True | s = [2, 3, 1] new_s = sorted(s, reverse=True) print(new_s) | [3, 2, 1] |
Ещё одной коллекцией в Python является кортеж (tuple
). Кортеж является неизменяемой упорядоченной коллекцией. В кортеже нельзя заменить значение элемента, добавить или удалить элемент. Простыми словами, кортеж — неизменяемый список. Свойство неизменяемости используется для защиты от случайных или намеренных изменений.
Задать кортеж можно следующим образом:
numbers = (1, 2, 3, 4, 5)
Если нужно создать кортеж из одного элемента, то запись будет такой:
one_number = (1, )
Запятая в примере показывает, что в скобках не совершается операция, а идёт перечисление элементов кортежа.
Для кортежей доступны те операции и методы списков, которые не изменяют исходный кортеж.
В качестве примера использования кортежей приведём программу для обмена значений двух переменных:
a = 1 b = 2 (a, b) = (b, a) # можно опустить круглые скобки и записать так a, b = b, a print(f"a = {a}, b = {b}")
Вывод программы:
a = 2, b = 1
Между коллекциями можно производить преобразования. Покажем их на примере преобразования строки в список и кортеж (элементы строки, символы становятся элементами списка и кортежа соответственно):
text = "Привет, мир!" list_symbols = list(text) tuple_symbols = tuple(text) text_from_list = str(list_symbols) print(list_symbols) print(tuple_symbols) print(text_from_list)
Вывод программы:
['П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!'] ('П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!') ['П', 'р', 'и', 'в', 'е', 'т', ',', ' ', 'м', 'и', 'р', '!']
Обратите внимание: преобразование коллекций к типу данных str
не объединяет элементы этой коллекции в одну строку, а возвращает представление коллекции в виде строки.
python — Разделить список на более мелкие списки (разделить пополам)
Я ищу способ легко разделить список Python пополам.
Так что если у меня есть массив:
A = [0,1,2,3,4,5]
Я бы смог получить:
B = [0,1,2] С = [3,4,5]
- питон
- список
- разделить
A = [1,2,3,4,5,6] В = А[:лен(А)//2] С = А[лен(А)//2:]
Если вам нужна функция:
def split_list(a_list): половина = len(a_list)//2 вернуть a_list[:половина], a_list[половина:] А = [1,2,3,4,5,6] B, C = разделенный_список (A)
2
Немного более общее решение (вы можете указать количество частей, которые вы хотите, а не просто разделить «пополам»):
def split_list(alist,want_parts=1): длина = len(алист) return [ alist[i*length // требуемые_части: (i+1)*длина // требуемые_части] для i в диапазоне (wanted_parts)] А = [0,1,2,3,4,5,6,7,8,9] распечатать split_list(A, Wanted_Parts=1) напечатать split_list(A, Wanted_Parts=2) напечатать split_list(A, Wanted_Parts=8)
8
f = лямбда A, n=3: [A[i:i+n] для i в диапазоне (0, len(A), n)] f(А)
n
— заданная длина массивов результатов
1
по умолчанию разделить (обр, размер): приход = [] в то время как len(arr) > размер: pice = обр[:размер] Arrs. append(рис.) обр = обр[размер:] обр.дополнение(обр.) возврат
Тест:
х=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] печать (разделить (х, 5))
результат:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]
2
Если вас не волнует порядок…
def split(list): вернуть список[::2], список[1::2]
list[::2]
получает каждый второй элемент в списке, начиная с 0-го элемента.
list[1::2]
получает каждый второй элемент в списке, начиная с 1-го элемента.
2
Использование нарезки списка. Синтаксис в основном my_list[start_index:end_index]
>>> i = [0,1,2,3,4,5] >>> i[:3] # то же, что и i[0:3] - захватывает с первого по третий индекс (0->2) [0, 1, 2] >>> i[3:] # то же, что и i[3:len(i)] - захватывает с четвертого индекса до конца [3, 4, 5]
Чтобы получить первую половину списка, вы срезаете от первого индекса до len(i)//2
(где //
— целочисленное деление, поэтому 3//2 даст результат
1 вместо недопустимого индекса списка
1. 5`):
>>> i[:len(i)/ /2] [0, 1, 2]
..и поменять местами значения, чтобы получить вторую половину:
>>> i[len(i)//2:] [3, 4, 5]
2
Б, С=А[:лен(А)/2],А[лен(А)/2:]
2
Вот распространенное решение, разбивающее arr на часть count
def split(arr, count): вернуть [arr[i::count] для i в диапазоне (count)]
1
деф сплиттер(А): B = A[0:len(A)//2] С = А[лен(А)//2:] возврат (В,С)
Я тестировал, и для принудительного деления int в Python 3 требуется двойная косая черта. Мой исходный пост был правильным, хотя wysiwyg по какой-то причине сломался в Opera.
1
Если у вас большой список, лучше использовать itertools и написать функцию для получения каждой части по мере необходимости:
from itertools import islice def make_chunks (данные, РАЗМЕР): это = итер (данные) # используйте `xragne`, если вы используете python 2. 7: для i в диапазоне (0, len (данные), SIZE): yield [k для k в islice(it, SIZE)]
Вы можете использовать это как:
A = [0, 1, 2, 3, 4, 5, 6] размер = длина (А) // 2 для образца в make_chunks (A, размер): печать (образец)
Вывод:
[0, 1, 2] [3, 4, 5] [6]
Спасибо @thefourtheye и @Bede Constantinides
Это похоже на другие решения, но немного быстрее.
# Использование: split_half([1,2,3,4,5]) Результат: ([1, 2], [3, 4, 5]) определение split_half (а): половина = длина (а) >> 1 вернуть[:половину],[половину:]
1
Существует официальный рецепт Python для более общего случая разбиения массива на более мелкие массивы размером 9.0037 и .
из itertools import izip_longest def grouper (n, iterable, fillvalue = None): «Собирать данные в куски или блоки фиксированной длины» # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx args = [iter(итерируемый)] * n вернуть izip_longest(fillvalue=fillvalue, *аргументы)
Этот фрагмент кода взят со страницы документации python itertools.
10 лет спустя.. Я подумал — почему бы не добавить еще:
arr = 'Какая-то случайная строка' * 10; п = 4 print([arr[e:e+n] для e в диапазоне(0,len(arr),n)])
Хотя приведенные выше ответы более или менее верны, у вас могут возникнуть проблемы, если размер вашего массива не делится на 2, поскольку результат a / 2
, являющийся нечетным, является числом с плавающей запятой в python 3.0 , и в более ранней версии, если вы укажете из __future__ import Division
в начале вашего скрипта. В любом случае вам лучше перейти на целочисленное деление, то есть a // 2
, чтобы получить «прямую» совместимость вашего кода.
# для питона 3 А = [0,1,2,3,4,5] л = лен(А)/2 В = А[:целое(л)] С = А [инт (л):]
Разделение общего списка решений на n частей с проверкой параметров:
def sp(l,n): # разбить список l на n частей если я: p = len(l), если n < 1, иначе len(l) // n # без разделения p = p, если p > 0, иначе 1 # разбить на элементы для i в диапазоне (0, len (l), p): выход l[i:i+p] еще: yield [] # пустой список split возвращает пустой список
Поскольку не было ограничений на то, какой пакет мы можем использовать. У Numpy есть функция с именем разделить
, с помощью которого вы можете легко разделить массив
любым удобным для вас способом.
Пример
импортировать numpy как np A = np.array (список ('abcdefg')) np.split(A, 2)
С подсказками @ChristopheD
def line_split(N, K=1): длина = длина (N) вернуть [N[i*длина/K:(i+1)*длина/K] для i в диапазоне (K)] А = [0,1,2,3,4,5,6,7,8,9] распечатать line_split(A,1) распечатать line_split(A,2)
Еще один взгляд на эту проблему в 2020 году… Вот обобщение проблемы. Я интерпретирую «разделить список пополам» как .. (т.е. только два списка, и не должно быть перелива на третий массив в случае нечетного и т. д.). Например, если длина массива равна 19а деление на два с использованием оператора // дает 9, и в итоге мы получим два массива длины 9 и один массив (третий) длины 1 (всего три массива). Если мы хотим, чтобы общее решение всегда давало два массива, я предполагаю, что нас устраивают результирующие двойные массивы, которые не равны по длине (один будет длиннее другого). И предполагается, что порядок смешанный (в данном случае чередующийся).
""" arrayinput --> - это массив длины N, который вы хотите разделить 2 раза """ ctr = 1 # позволяет инициализировать счетчик держатель_1 = [] держатель_2 = [] для i в диапазоне (len (arrayinput)): если ctr == 1 : держатель_1.append (ввод массива [i]) Элиф ctr == 2: держатель_2.append (ввод массива [i]) ctr += 1 if ctr > 2 : # если больше 2 то сбрасываем клик = 1
Эта концепция работает для любого количества разделов списка, как вы хотите (вам придется настроить код в зависимости от того, сколько частей списка вы хотите). И интерпретируется довольно просто. Чтобы ускорить процесс, вы можете даже написать этот цикл на cython/C/C++, чтобы ускорить процесс. Опять же, я пробовал этот код на относительно небольших списках ~ 10 000 строк, и он завершается за доли секунды.
Мои пять копеек.
Спасибо!
из itertools import islice Ввод = [2, 5, 3, 4, 8, 9, 1] small_list_length = [1, 2, 3, 1] Input1 = итер (ввод) Результат = [список (islice (Input1, elem)) для элемента в small_list_length] print("Список ввода:", Ввод) print("Список разделенной длины: ", small_list_length) print("Список после разделения", Результат)
1
Вы можете попробовать что-то подобное с numpy
импортировать numpy как np np. array_split ([1,2,3,4,6,7,8], 2)
результат:
[массив ([1, 2, 3, 4]), массив ([6, 7, 8])]
Если у вас Python 3.12, используйте пакетный режим:
из itertools import пакетный массив = [1,2,3,4,5,6,7,8,9,0] куски = пакетные (массив, длина (массив)/2 + 1)
Это разбивает массив на куски указанного размера (что является гораздо более распространенной операцией, чем разбиение на два пара).
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
python — Как сделать плоский список из списка списков?
Дан список списков l
,
flat_list = [элемент для подсписка в l для элемента в подсписке]
что означает:
flat_list = [] для подсписка в l: для элемента в подсписке: flat_list. append (элемент)
быстрее, чем ярлыки, опубликованные до сих пор. ( l
список для выравнивания.)
Вот соответствующая функция:
def flatten(l): вернуть [элемент для подсписка в l для элемента в подсписке]
В качестве доказательства можно использовать модуль timeit
из стандартной библиотеки:
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[элемент для подсписка в l для элемента в подсписке]' 10000 циклов, лучшее из 3: 143 мкс на цикл $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'сумма(l, [])' 1000 циклов, лучшее из 3: 969 мкс на цикл $ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'уменьшить (лямбда x,y: x+y ,л)' 1000 циклов, лучшее из 3: 1,1 мс на цикл
Объяснение: ярлыки основаны на +
(включая подразумеваемое использование в сумме
) по необходимости составляют O(L**2)
, когда есть L подсписков — поскольку список промежуточных результатов становится длиннее, на каждом шаге появляется новый промежуточный результат. объект списка выделяется, и все элементы в предыдущем промежуточном результате должны быть скопированы (а также несколько новых, добавленных в конце). Итак, для простоты и без фактической потери общности предположим, что у вас есть L подсписков по I элементов в каждом: первые I элементов копируются туда и обратно L-1 раз, вторые I элементов L-2 раза и так далее; общее количество копий равно I, умноженной на сумму x для x от 1 до L без учета, т. е. I * (L**2)/2
.
Генерация списка просто генерирует один список, один раз, и копирует каждый элемент (из исходного места жительства в список результатов) также ровно один раз.
12
Вы можете использовать itertools.chain()
:
>>> import itertools >>> list2d = [[1,2,3], [4,5,6], [7], [8,9]] >>> объединено = список (itertools.chain (* list2d))
Или вы можете использовать itertools.chain.from_iterable()
который не требует распаковки списка оператором *
:
>>> import itertools >>> list2d = [[1,2,3], [4,5,6], [7], [8,9]] >>> объединено = список (itertools. chain.from_iterable (list2d))
Этот подход, возможно, более удобочитаем, чем [элемент для подсписка в l для элемента в подсписке]
и, кажется, также быстрее:
$ python3 -mtimeit -s'l=[[1,2,3],[ 4,5,6], [7], [8,9]]*99;импортировать itertools' 'список(itertools.chain.from_iterable(l))' 20 000 циклов, лучшее из 5: 10,8 мкс на цикл $ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[элемент для подсписка в l для элемента в подсписке]' 10 000 циклов, лучшее из 5: 21,7 мкс на цикл $ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'сумма(l, [])' 1000 циклов, лучшее из 5: 258 мкс на цикл $ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99; из functools импортировать уменьшить' 'уменьшить (лямбда x, у: х+у,1)' 1000 циклов, лучшее из 5: 292 мкс на цикл $ python3 --версия Питон 3.7.5rc1
5
Примечание автора : Это очень неэффективно. Но весело, потому что моноиды потрясающие.
>>> xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> сумма(xss, []) [1, 2, 3, 4, 5, 6, 7, 8, 9]
sum
суммирует элементы итерируемого xss
и использует второй аргумент в качестве начального значения []
для суммы. (Исходное значение по умолчанию — 0
, что не является списком.)
Поскольку вы суммируете вложенные списки, вы фактически получаете [1,3]+[2,4]
в результате sum([[1,3],[2,4]],[])
, что равно [1,3,2,4]
.
Обратите внимание, что работает только со списками списков. Для списков списков списков вам понадобится другое решение.
5
Я проверил большинство предлагаемых решений с помощью perfplot (мой любимый проект, по сути, оболочка вокруг timeit
) и нашел
import functools оператор импорта functools.reduce (operator.iconcat, a, [])
будет самым быстрым решением как при объединении множества небольших списков, так и при объединении нескольких длинных списков. ( operator.iadd
одинаково быстро.)
Более простой и приемлемый вариант
out = [] для подсписка в a: out.extend(подсписок)
Если количество подсписков велико, это работает немного хуже, чем приведенное выше предложение.
Код для воспроизведения сюжета:
import functools импортировать itertools оператор импорта импортировать numpy как np импортировать перфплот деф forfor(a): вернуть [элемент для подсписка для элемента в подсписке] def сумма_бракетов (а): возвращаемая сумма (а, []) определение functools_reduce (а): вернуть functools.reduce (operator.concat, a) определение functools_reduce_iconcat (а): вернуть functools.reduce (operator.iconcat, a, []) определение itertools_chain (а): список возврата (itertools.chain.from_iterable (a)) определение numpy_flat (а): список возврата (np.array(a).flat) определение numpy_concatenate (а): список возврата (np.concatenate (a)) защита расширения (а): выход = [] для подсписка в a: out. extend(подсписок) вернуться б = perfplot.bench ( setup=лямбда n: [список (диапазон (10))] * n, # setup=лямбда n: [список(диапазон(n))] * 10, ядра=[ для, сумма_скобки, functools_reduce, functools_reduce_iconcat, itertools_chain, numpy_flat, numpy_concatenate, продлевать, ], n_range=[2 ** k для k в диапазоне (16)], xlabel="количество списков (длиной 10)", # xlabel="длинные списки (всего 10 списков)" ) b.save("out.png") б.показать()
7
Использование functools.reduce
, который добавляет накопленный список xs
к следующему списку ys
:
из functools import reduce xss = [[1,2,3], [4,5,6], [7], [8,9]] out = уменьшить (лямбда xs, ys: xs + ys, xss)
Вывод:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Более быстрый способ с использованием operator. concat
:
из functools import reduce оператор импорта хсс = [[1,2,3], [4,5,6], [7], [8,9]] out = уменьшить (operator.concat, xss)
Вывод:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
3
Вот общий подход, который применяется к числам , строкам , вложенным спискам и смешанным контейнерам . Это может сгладить как простые, так и сложные контейнеры (см. также Demo ).
Код
из ввода import Iterable #из коллекций импортировать Iterable # < py38 деф сгладить (предметы): """Вывод элементов из любого вложенного итерируемого объекта; см. Справочник.""" для x в пунктах: если isinstance(x, Iterable), а не isinstance(x, (str, bytes)): для sub_x в flatten(x): выход sub_x еще: выход х
Примечания :
- В Python 3
yield from flatten(x)
может заменитьдля sub_x в flatten(x): yield sub_x
- В Python 3. 8 абстрактные базовые классы перемещены из
collection.abc
в модульtyping
.
Демо
простой = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] список (сгладить (простой)) # [1, 2, 3, 4, 5, 6, 7, 8, 9] сложно = [[1, [2]], (3, 4, {5, 6}, 7), 8, "9"] # числа, строки, вложенные и смешанные список (сгладить (сложно)) # [1, 2, 3, 4, 5, 6, 7, 8, '9']
Справочный номер
- Этот раствор изменен на основе рецепта Бизли, Д. и Б. Джонс. Рецепт 4.14, Поваренная книга Python, 3-е изд., O'Reilly Media Inc. Севастополь, Калифорния: 2013.
- Найден более ранний пост SO, возможно, оригинальная демонстрация.
7
Чтобы сгладить глубоко вложенную структуру данных, используйте iteration_utilities.deepflatten
1 :
>>> из iteration_utilities импортировать deepflatten >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> list(deepflatten(l, depth=1)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> l = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]] >>> список (глубокое сглаживание (l)) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Это генератор, поэтому вам нужно привести результат к списку
или явно перебрать его.
Чтобы сгладить только один уровень, и если каждый из элементов сам по себе является итерируемым, вы также можете использовать iteration_utilities.flatten
, который сам по себе является тонкой оболочкой вокруг itertools.chain.from_iterable
:
>>> from iteration_utilities import flatten >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> список (сгладить (l)) [1, 2, 3, 4, 5, 6, 7, 8, 9]
Просто чтобы добавить некоторые тайминги (на основе ответа Нико Шлемера, который не включал функцию, представленную в этом ответе):
Это логарифмический график для охвата огромного диапазона значений. Для качественных рассуждений: чем меньше, тем лучше.
Результаты показывают, что если итерация содержит только несколько внутренних итераций, то sum
будет самой быстрой, однако для длинных итераций только itertools.chain.from_iterable
, iteration_utilities.deepflatten
или вложенное понимание имеют приемлемую производительность с itertools. chain.from_iterable
— самый быстрый (как уже заметил Нико Шлемер).
из цепочки импорта itertools из functools импортировать уменьшить from collections import Iterable # или from collections.abc import Iterable оператор импорта из iteration_utilities импортировать deepflatten определение вложенного_списка_пополнения (списков): return [элемент для подсписка в списках для элемента в подсписке] определение itertools_chain_from_iterable (список): список возврата (chain.from_iterable (lsts)) защита pythons_sum (список): возвращаемая сумма (список, []) защита уменьшить_добавить (список): вернуть уменьшить (лямбда x, y: x + y, lsts) защита pylangs_flatten (список): список возврата (сглаживание (списки)) деф сгладить (предметы): """Вывод элементов из любого вложенного итерируемого объекта; см. REF.""" для x в пунктах: если isinstance(x, Iterable), а не isinstance(x, (str, bytes)): выход из сглаживания (x) еще: выход х защита уменьшить_concat (список): вернуть уменьшить (operator. concat, lsts) def iteration_utilities_deepflatten (список): список возврата (deepflatten (lsts, depth = 1)) из бенчмарка импорта simple_benchmark б = эталон ( [nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add, pylangs_flatten, reduce_concat, iteration_utilities_deepflatten], arguments={2**i: [[0]*5]*(2**i) для i в диапазоне (1, 13)}, arguments_name = 'количество внутренних списков' ) б.участок()
1 Отказ от ответственности: я являюсь автором этой библиотеки
0
Мне кажется самым простым следующее:
>>> import numpy as np >>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] >>> печать (np.concatenate (l)) [1 2 3 4 5 6 7 8 9]
1
Рассмотрите возможность установки пакета more_itertools
.
> pip установить more_itertools
Он поставляется с реализацией для flatten
(источник, из рецептов itertools):
import more_itertools лст = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] список (more_itertools. flatten (lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Примечание. Как указано в документации, для flatten
требуется список списков. См. ниже о сглаживании более нерегулярных входных данных.
Начиная с версии 2.4, вы можете сглаживать более сложные вложенные итерации с помощью more_itertools.collapse
(источник предоставлен abarnet).
лст = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] список (more_itertools.collapse (lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9] lst = [[1, 2, 3], [[4, 5, 6]], [[[7]]], 8, 9] # сложная вложенность список (more_itertools.collapse (lst)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
4
Причина, по которой ваша функция не работает, заключается в том, что расширение расширяет массив на месте и не возвращает его. Вы все еще можете вернуть x из лямбда, используя что-то вроде этого:
уменьшить (лямбда x, y: x.extend (y) или x, l)
Примечание: расширение более эффективно, чем + в списках.
2
matplotlib.cbook.flatten()
будет работать для вложенных списков, даже если они вложены глубже, чем в примере.
импорт матплотлиб л = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] печать (список (matplotlib.cbook.flatten (l))) l2 = [[1, 2, 3], [4, 5, 6], [7], [8, [9, 10, [11, 12, [13]]]]] печать (список (matplotlib.cbook.flatten (l2)))
Результат:
[1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Это в 18 раз быстрее, чем подчеркивание. Среднее время более 1000 попыток подчеркивания._.flatten: 4,63e-04 сек. (время для подчеркивания._)/(время для matplotlib.cbook) = 18.1233394636
0
Согласно вашему списку [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
, который является 1 уровнем списка, мы можем просто использовать sum(list,[])
без использования каких-либо библиотек
sum([[1, 2, 3], [4, 5, 6], [7] , [8, 9]],[]) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Чтобы расширить преимущества этого метода, когда внутри существует кортеж или число. Просто добавьте функцию сопоставления для каждого элемента с помощью map
в список
# Только для кортежа сумма (список (карта (список, [[1, 2, 3], (4, 5, 6), (7,), [8, 9]])), []) # [1, 2, 3, 4, 5, 6, 7, 8, 9] #В общем преобразование по определению (х): если тип (x) — int или тип (x) — float: вернуть [х] еще: список возврата (х) сумма (список (карта (преобразовать, [[1, 2, 3], (4, 5, 6), 7, [8, 9)]]))[]) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
Здесь есть четкое объяснение недостатка памяти для этого подхода. Короче говоря, он рекурсивно создает объекты списка, которых следует избегать 🙁
3
Можно также использовать квартиру NumPy:
импортировать numpy как np список (np.массив (l).flat)
Работает, только если подсписки имеют одинаковые размеры.
0
Вы можете использовать метод списка
расширения
. Он оказался самым быстрым:
flat_list = [] для подсписка в l: flat_list.extend (подсписок)
Производительность:
импортировать functools импортировать itertools импортировать numpy оператор импорта импортировать перфплот определение functools_reduce_iconcat (а): вернуть functools.reduce (operator.iconcat, a, []) определение itertools_chain (а): список возврата (itertools.chain.from_iterable (a)) определение numpy_flat (а): список возврата (numpy.array(a).flat) защита расширения (а): п = [] список (карта (n.extend, а)) вернуть н перфплот.шоу( настройка = лямбда n: [список (диапазон (10))] * n, ядра = [ functools_reduce_iconcat, расширение, itertools_chain, numpy_flat ], n_range = [2**k для k в диапазоне (16)], xlabel = 'количество списков', )
Вывод:
0
Есть несколько ответов с такой же рекурсивной схемой добавления, как показано ниже, но ни один из них не использует try
, что делает решение более надежным и Pythonic .
по уплощению (itr): для x в itr: пытаться: выход из сглаживания (x) кроме TypeError: выход х
Использование : это генератор, и вы обычно хотите заключить его в итерируемый конструктор, например list()
или tuple()
или используйте его в цикле for
.
Преимущества этого решения:
- работает с любыми итерируемыми (даже будущими!)
- работает с любой комбинацией и глубиной вложенности
- работает также, если верхний уровень содержит пустые элементы
- нет зависимостей
- быстро и эффективно (вы можете частично сгладить вложенную итерацию, не тратя время на оставшуюся часть, которая вам не нужна)
- универсальный (вы можете использовать его для создания итерации по вашему выбору или в цикле)
N.B.: Начиная с , все итерации сглаживаются, строки разбиваются на последовательности отдельных символов. Если вам не нравится/не нужно такое поведение, вы можете использовать следующую версию, которая отфильтровывает сглаживание итерируемых объектов, таких как строки и байты:
def flatten(itr): если тип (itr) в (строка, байты): дать это еще: для x в itr: пытаться: выход из сглаживания (x) кроме TypeError: выход х
2
Примечание . Нижеприведенное относится к Python 3.3+, поскольку в нем используется yield_from
. six
тоже сторонний пакет, хоть и стабильный. В качестве альтернативы вы можете использовать sys.version
.
В случае obj = [[1, 2,], [3, 4], [5, 6]]
все решения здесь хороши, включая понимание списка и itertools.chain.from_iterable
.
Однако рассмотрим несколько более сложный случай:
>>> obj = [[1, 2, 3], [4, 5], 6, 'abc', [7], [8, [9, 10] ]]
Здесь есть несколько проблем:
- Один элемент,
6
, является просто скаляром; он не повторяемый, поэтому указанные выше маршруты здесь не работают. - Один элемент,
'abc'
, является технически итерируемым (всеstr
s). Однако, читая немного между строк, вы не хотите рассматривать его как таковой — вы хотите рассматривать его как один элемент. - Последний элемент,
[8, [9, 10]]
, сам по себе является вложенным итерируемым объектом. Базовое понимание списка иchain.from_iterable
извлекают только «1 уровень вниз».
Вы можете исправить это следующим образом:
>>> from collections import Iterable >>> из шести импортируемых string_types >>> def flatten(obj): ... для i в объекте: ... если isinstance(i, Iterable), а не isinstance(i, string_types): ... выход из flatten(i) ... еще: ... выход я >>> список (сгладить (объект)) [1, 2, 3, 4, 5, 6, 'абв', 7, 8, 9, 10]
Здесь вы проверяете, что подэлемент (1) является итерируемым с помощью Iterable
, ABC из itertools
, но также хотите убедиться, что (2) элемент не «строкоподобный».
1
Если вы готовы пожертвовать небольшим количеством скорости ради более чистого вида, вы можете использовать numpy.concatenate().tolist()
или numpy.concatenate().ravel().tolist()
:
импорт numpy л = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99 %timeit numpy.concatenate(l).ravel().tolist() 1000 циклов, лучший из 3: 313 мкс на цикл %timeit numpy.concatenate(l).tolist() 1000 циклов, лучшее из 3: 312 мкс на цикл %timeit [элемент для подсписка в l для элемента в подсписке] 1000 циклов, лучшее из 3: 31,5 мкс на цикл
Вы можете узнать больше здесь, в документации, numpy.concatenate и numpy.ravel.
2
по умолчанию сглаживание (список): если список == []: возвращаться [] elif type(alist) не входит в список: возврат [алист] еще: return flatten(alist[0]) + flatten(alist[1:])
1
Мне нужно решение, которое может иметь дело с множественной вложенностью (например, [[1], [[[2]], [3]]], [1, 2, 3]
), но также не будет рекурсивным (У меня был большой уровень рекурсии, и я получил ошибку рекурсии.
Вот что я придумал:
def _flatten(l) -> Iterator[Any]: стек = l.copy() в то время как стек: элемент = стек.поп() если isinstance (элемент, список): stack.extend(элемент) еще: элемент доходности def flatten(l) -> Iterator[Any]: вернуть в обратном порядке (список (_flatten (l)))
и тесты:
@pytest.mark.parametrize('input_list, expect_output', [ ([1, 2, 3], [1, 2, 3]), ([[1], 2, 3], [1, 2, 3]), ([[1], [2], 3], [1, 2, 3]), ([[1], [2], [3]], [1, 2, 3]), ([[1], [[2]], [3]], [1, 2, 3]), ([[1], [[[2]], [3]]], [1, 2, 3]), ]) def test_flatten (входной_список, ожидаемый_выход): список утверждений (выравнивание (входной_список)) == ожидаемый_выход
Возможно, это не самый эффективный способ, но я подумал поставить однострочный (на самом деле двухстрочный). Обе версии будут работать с вложенными списками произвольной иерархии и использовать возможности языка (Python 3. 5) и рекурсию.
по умолчанию make_list_flat (l): флист = [] flist.extend ([l]), если (тип (l) не является списком) else [flist.extend (make_list_flat (e)) для e в l] возвратный список а = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [ [16, 17], 18]]]]]] flist = make_list_flat (а) распечатать (флист)
Выход:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Это работает в первую очередь в глубину. Рекурсия идет вниз, пока не найдет элемент, не входящий в список, а затем расширяет локальную переменную flist
, а затем откатывает его к родителю. Всякий раз, когда возвращается flist
, он расширяется до родительского flist
в понимании списка. Поэтому в корне возвращается плоский список.
Приведенный выше создает несколько локальных списков и возвращает их, которые используются для расширения родительского списка. Я думаю, что для этого может быть создан gloabl flist
, как показано ниже.
а = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15] , [[16, 17], 18]]]]]] флист = [] защита make_list_flat (l): flist.extend ([l]) if (тип (l) не является списком) else [make_list_flat (e) для e в l] make_list_flat(а) распечатать (флист)
Вывод снова
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
Хотя на данный момент я не уверен в эффективности.
1
Не однострочный, но, увидев все ответы здесь, я думаю, что в этом длинном списке пропущено некоторое сопоставление с образцом, так что вот оно 🙂
Два метода, вероятно, неэффективны, но в любом случае их легко читать по крайней мере я; возможно, я избалован функциональным программированием):
по умолчанию плоский(x): совпадение х: случай []: возвращаться [] случай [[*подсписок], *r]: return [*sublist, *flat(r)]
Вторая версия рассматривает списки списков списков. .. независимо от вложенности:
def flat(x): совпадение х: случай []: возвращаться [] случай [[*подсписок], *r]: return [*flat(подсписок), *flat(r)] случай [h, *r]: вернуть [h, *flat (r)]
Если вы хотите удалить все и сохранить отдельный список элементов, вы также можете использовать это.
list_of_lists = [[1,2], [2,3], [3,4]] list(set.union(*[set(s) for s in list_of_lists]))
Если у вас есть массив a
:
a = np.array([[1,2], [3,4]]) a.flatten('C')
производит:
[1, 2, 3, 4]
np.flatten
также принимает другие параметры:
-
C
: -
Ф
-
А
-
К
Более подробная информация о параметрах доступна здесь.
1
Еще один необычный подход, который работает для разнородных и однородных списков целых чисел:
, набрав import List def flatten(l: list) -> List[int]: """Свести произвольный глубоко вложенный список списков целых чисел. Примеры: >>> сгладить ([1, 2, [1, [10]]]) [1, 2, 1, 10] Аргументы: l: Союз[l, Союз[int, Список[int]] Возвращает: Плоский список целых чисел """ return [int(i.strip('[]')) для i в str(l).split(',')]
6
Нерекурсивная функция для выравнивания списков списков любой глубины:
def flatten_list(list1): выход = [] внутри = список1 пока внутри: х = внутри.поп(0) если isinstance(x, список): внутри[0:0] = х еще: out.append(x) вернуться л = [[[1,2],3,[4,[[5,6],7],[8]]],[9,10,11]] flatten_list (л) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Для списка, содержащего несколько списков, здесь рекурсивное решение, которое работает для меня и, надеюсь, правильное:
# Вопрос 4 def flatten (input_ls = []) -> []: res_ls = [] res_ls = flatten_recursive (input_ls, res_ls) print("Окончательное решение для выравнивания списка: \n", res_ls) вернуть res_ls def flatten_recursive(input_ls=[], res_ls=[]) -> []: tmp_ls = [] для я в input_ls: если isinstance(i, int): res_ls. append(i) еще: tmp_ls = я tmp_ls.append (flatten_recursive (i, res_ls)) печать (res_ls) вернуть res_ls flatten([0, 1, [2, 3], 4, [5, 6]]) # проверка сгладить ([0, [[[1]]], [[2, 3], [4, [[5, 6]]]]])
Вывод:
[0, 1, 2, 3] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6] Окончательное решение для выравнивания списка: [0, 1, 2, 3, 4, 5, 6] [0, 1] [0, 1] [0, 1] [0, 1, 2, 3] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6] [0, 1, 2, 3, 4, 5, 6] Окончательное решение для выравнивания списка: [0, 1, 2, 3, 4, 5, 6]
Я бы предложил использовать генераторы с оператором yield и yield from . Вот пример:
из collections.abc import Iterable def flatten (элементы, ignore_types = (bytes, str)): """ Свести все вложенные списки в один. Игнорирование выравнивания итерируемых типов str и bytes по умолчанию. """ для x в пунктах: если isinstance(x, Iterable), а не isinstance(x, ignore_types): выход из сглаживания (x) еще: выход х значения = [7, [4, 3, 5, [7, 3], (3, 4), ('A', {'B', 'C'})]] для v в сглаживании (значения): печать (v)
Если я хочу добавить что-то к замечательным предыдущим ответам, вот моя рекурсивная функция flatten
, которая может сглаживать не только вложенные списки, но и любой заданный контейнер или вообще любой объект, который может выбрасывать элементы. Это также работает для любой глубины вложенности, и это ленивый итератор, который выдает элементы в соответствии с запросом:
def flatten(iterable): # Эти типы не будут считаться последовательностью или вообще контейнером исключить = строка, байт для я в итерации: пытаться: если isinstance(i, исключить): поднять TypeError итер (я) кроме TypeError: выход я еще: выход из сглаживания (i)
Таким образом, вы можете исключить типы, которые не хотите сглаживать, например str
или что-то еще.
Идея в том, что если объект может пройти iter()
, он готов выдать элементы. Таким образом, итерируемый объект может иметь даже выражения генератора в качестве элемента.
Кто-то может возразить: почему вы написали это, когда ОП об этом не просил? Хорошо, ты прав. Я просто чувствовал, что это может помочь кому-то (как и мне).
Тестовые случаи:
lst1 = [1, {3}, (1, 6), [[3, 8]], [[[5]]], 9, ((((2,),),),)] lst2 = ['3', B'A', [[[(i ** 2 для i в диапазоне (3))]]], диапазон (3)] распечатать (список (сгладить (lst1))) распечатать (список (сгладить (lst2)))
Вывод:
[1, 3, 1, 6, 3, 8, 5, 9, 2] ['3', б'А', 0, 1, 4, 0, 1, 2]
Вот подход, которого я не видел в других ответах.