Я ищу способ легко разделить список Python пополам.
Итак, если у меня есть массив:
A = [0,1,2,3,4,5]
Я смогу получить:
B = [0,1,2]
C = [3,4,5]
Я ищу способ легко разделить список Python пополам.
Итак, если у меня есть массив:
A = [0,1,2,3,4,5]
Я смогу получить:
B = [0,1,2]
C = [3,4,5]
A = [1,2,3,4,5,6]
B = A[:len(A)//2]
C = A[len(A)//2:]
Если вам нужна функция:
def split_list(a_list):
half = len(a_list)//2
return a_list[:half], a_list[half:]
A = [1,2,3,4,5,6]
B, C = split_list(A)
B = A[:(len(A) // 10) * 8]
C = A[(len(A) // 10) * 8:]
- person Gergely M; 04.03.2019
Немного более общее решение (вы можете указать необходимое количество частей, а не просто разделить их пополам):
РЕДАКТИРОВАТЬ: обновленное сообщение для обработки нечетных длин списков
EDIT2: обновите сообщение еще раз на основе информативных комментариев Брайанса.
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts]
for i in range(wanted_parts) ]
A = [0,1,2,3,4,5,6,7,8,9]
print split_list(A, wanted_parts=1)
print split_list(A, wanted_parts=2)
print split_list(A, wanted_parts=8)
//
означает целочисленное деление. Их не следует упускать из виду, поскольку они очень важны для выполнения этой работы.
- person Alphadelta14; 20.11.2013
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)
n
- предопределенная длина массивов результатов
def split(arr, size):
arrs = []
while len(arr) > size:
pice = arr[:size]
arrs.append(pice)
arr = arr[size:]
arrs.append(arr)
return arrs
Тестовое задание:
x=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
print(split(x, 5))
результат:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]
for i,j in zip(list,lengths): print(split(i,j))
. Списки list
и lengths
имеют одинаковую длину. j чередуется: 5,4,5,4,5, и функция разделения работает с первыми двумя чередованиями, то есть разбивает первый i
списка на 5 и 4, НО на следующей итерации он разбивает его на 4,4 , 1. : \ Пожалуйста, ответьте, если вы хотите, чтобы я объяснил больше (задайте новый вопрос)
- person Mike Issa; 05.02.2016
Если вас не волнует порядок ...
def split(list):
return list[::2], list[1::2]
list[::2]
получает каждый второй элемент в списке, начиная с 0-го элемента. list[1::2]
получает каждый второй элемент в списке, начиная с 1-го элемента.
list
с затенением list(...)
встроенного. Я видел, как lst
и list_
обычно используются, чтобы избежать этого.
- person Taylor Edmiston; 27.02.2017
Вот общее решение, разделить arr на счетную часть
def split(arr, count):
return [arr[i::count] for i in range(count)]
Использование нарезки списка. Синтаксис в основном my_list[start_index:end_index]
>>> i = [0,1,2,3,4,5]
>>> i[:3] # same as i[0:3] - grabs from first to third index (0->2)
[0, 1, 2]
>>> i[3:] # same as i[3:len(i)] - grabs from fourth index to end
[3, 4, 5]
Чтобы получить первую половину списка, вы отрезаете от первого индекса до len(i)//2
(где //
- целочисленное деление, поэтому _5my_list[start_index:end_index]
6_1.5`):
>>> i[:len(i)//2]
[0, 1, 2]
..и поменяйте местами значения, чтобы получить вторую половину:
>>> i[len(i)//2:]
[3, 4, 5]
3//2
дает 1
, затем вы получаете i[:1]
, что дает [0]
, и i[1:]
, что дает [1, 2]
- person dbr; 16.05.2019
def splitter(A):
B = A[0:len(A)//2]
C = A[len(A)//2:]
return (B,C)
Я тестировал, и двойная косая черта требуется для принудительного деления int в python 3. Мой исходный пост был правильным, хотя по какой-то причине wysiwyg сломался в Opera.
Если у вас большой список, лучше использовать itertools и написать функцию для получения каждой части по мере необходимости:
from itertools import islice
def make_chunks(data, SIZE):
it = iter(data)
# use `xragne` if you are in python 2.7:
for i in range(0, len(data), SIZE):
yield [k for k in islice(it, SIZE)]
Вы можете использовать это как:
A = [0, 1, 2, 3, 4, 5, 6]
size = len(A) // 2
for sample in make_chunks(A, size):
print(sample)
Результат:
[0, 1, 2]
[3, 4, 5]
[6]
Благодаря @thefourtheye и @ Беде Константинидес
Существует официальный рецепт Python для более обобщенного случая разделения массива на более мелкие массивы размером n
.
from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
Этот фрагмент кода взят со страницы страницы документации python itertools.
Это похоже на другие решения, но немного быстрее.
# Usage: split_half([1,2,3,4,5]) Result: ([1, 2], [3, 4, 5])
def split_half(a):
half = len(a) >> 1
return a[:half], a[half:]
Спустя 10 лет .. Подумал - а почему бы не добавить еще:
arr = 'Some random string' * 10; n = 4
print([arr[e:e+n] for e in range(0,len(arr),n)])
Хотя приведенные выше ответы более или менее верны, вы можете столкнуться с проблемами, если размер вашего массива не делится на 2, поскольку в результате a / 2
, нечетное значение, является плавающим в python 3.0, а в более ранней версии, если вы указываете from __future__ import division
в начале вашего скрипта. В любом случае лучше использовать целочисленное деление, то есть a // 2
, чтобы получить "прямую" совместимость вашего кода.
С подсказками от @ChristopheD
def line_split(N, K=1):
length = len(N)
return [N[i*length/K:(i+1)*length/K] for i in range(K)]
A = [0,1,2,3,4,5,6,7,8,9]
print line_split(A,1)
print line_split(A,2)
Еще один подход к этой проблеме в 2020 году ... Вот обобщение проблемы. Я интерпретирую «разделить список пополам» как ... (т.е. только два списка, и не должно быть перетекания в третий массив в случае нечетного и т. Д.). Например, если длина массива равна 19, а деление на два с использованием оператора // дает 9, в результате мы получим два массива длиной 9 и один массив (третий) длиной 1 (итого, всего три массива). Если мы хотим, чтобы общее решение давало два массива все время, я предполагаю, что мы довольны результирующими двойными массивами, которые не равны по длине (один будет длиннее другого). И что предполагается, что порядок смешанный (в данном случае чередующийся) - это нормально.
"""
arrayinput --> is an array of length N that you wish to split 2 times
"""
ctr = 1 # lets initialize a counter
holder_1 = []
holder_2 = []
for i in range(len(arrayinput)):
if ctr == 1 :
holder_1.append(arrayinput[i])
elif ctr == 2:
holder_2.append(arrayinput[i])
ctr += 1
if ctr > 2 : # if it exceeds 2 then we reset
ctr = 1
Эта концепция работает для любого количества разделов списка по вашему желанию (вам придется настроить код в зависимости от того, сколько частей списка вы хотите). И довольно просто интерпретировать. Чтобы ускорить процесс, вы даже можете написать этот цикл на cython / C / C ++, чтобы ускорить процесс. Опять же, я пробовал этот код на относительно небольших списках ~ 10 000 строк, и он завершается за доли секунды.
Всего два цента.
Спасибо!
Общий список решения разбит на n частей с проверкой параметров:
def sp(l,n):
# split list l into n parts
if l:
p = len(l) if n < 1 else len(l) // n # no split
p = p if p > 0 else 1 # split down to elements
for i in range(0, len(l), p):
yield l[i:i+p]
else:
yield [] # empty list split returns empty list
//
, как уже говорили другие.
- person Stack; 26.11.2020