목록을 더 작은 목록으로 나누기 (반으로 분할)


150

파이썬 목록을 쉽게 반으로 나눌 수있는 방법을 찾고 있습니다.

그래서 배열이 있다면 :

A = [0,1,2,3,4,5]

나는 얻을 수있을 것입니다 :

B = [0,1,2]

C = [3,4,5]

답변:


226
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)

70
파이썬 3에서 int 나누기를 강요해야합니다. // 필수입니다.
Stefan Kendall

4
좋은 해결책입니다. 감사합니다. 또한 Python3 80/20 같은 분수와 함께 작동B = A[:(len(A) // 10) * 8] C = A[(len(A) // 10) * 8:]
게르 겔리 M

87

좀 더 일반적인 해결책 ( '반으로 나누지 않고 원하는 부분 수를 지정할 수 있습니다) :

편집 : 홀수 목록 길이를 처리하도록 게시물이 업데이트되었습니다.

EDIT2 : Brians 유익한 의견에 따라 게시물을 다시 업데이트하십시오.

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)

2
목록이 균등하게 분할되지 않으면 (예 : split_list ([1,2,3], 2)) 실제로 want_parts + 1 목록을 반환합니다.
Brian

3
내가 생각하는 더 좋은 방법은 : length = len (alist); range (wanted_parts)]의 i에 대해 [alist [i * length // wanted_parts : (i + 1) * length // wanted_parts]]를 리턴합니다. 당신이 얻을에도 항상 가능한 분배와 같은을 얻고, 그 방법은 정확히 항목 wanted_parts ([] 심지어 패드를 경우 wanted_parts> 렌 (A))
브라이언

2
안녕 .. "//"기호는 무엇을 의미 하는가 ??
frazman

2
@Fraz Its는 인라인 주석으로 의미됩니다. "// wanted_parts"및 "// wanted_parts"를 무시하여 스크립트를 실행하십시오.
PunjCoder

19
//정수 나누기를 의미합니다. 이 작업을 수행하는 데 필수적이므로 생략해서는 안됩니다.
Alphadelta14

43
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)

n -사전 정의 된 길이의 결과 배열


1
이것은 내 상황에서 훌륭하게 작동하지만 각 목록의 다른 모든 마지막 색인을 자체 목록에 추가합니다. 설명하기 어려운. 도움이 될 경우 회신 해 주시면 더 설명하겠습니다.
Mike Issa

34
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]]

1
리스트를 행렬로 변환 하는데도 유용
mpgn

이것은 작동하지만 그다지 좋지는 않습니다. 루프 에서이 기능을 사용하고 있으며 길이가 다릅니다. 다시 말해 : for i,j in zip(list,lengths): print(split(i,j)). listlengths목록은 같은 길이를 갖는다. j는 번갈아 가며 : 5,4,5,4,5, split 함수는 처음 두 번의 교체에서 작동합니다. 즉, i목록 의 첫 번째 를 5와 4로 나누지 만 다음 반복에서는 4,4로 나눕니다. 1. : \ 좀 더 설명해 주시면 답장 해주세요 (새 질문 게시)
Mike Issa

15

주문에 신경 쓰지 않으면 ...

def split(list):  
    return list[::2], list[1::2]

list[::2]0 번째 요소부터 시작하여 목록의 모든 두 번째 요소를 가져옵니다.
list[1::2]목록에서 첫 번째 요소부터 시작하여 매 초마다 요소를 가져옵니다.


4
내장 list섀도 잉으로 인수 이름을 신중하게 지정하십시오 list(...). 나는 본 적이 lstlist_그것을 방지하기 위해 일반적으로 사용되는.
Taylor Edmiston

3
이것은 대부분의 pythonic를 느낀다 (잘못된 이름을 무시 함)
Tjorriemorrie


11

다음은 일반적인 해결책입니다. arr을 카운트 부분으로 나눕니다.

def split(arr, count):
     return [arr[i::count] for i in range(count)]

이것은 목록의 순서를 잃는다
Timmah

9
def splitter(A):
    B = A[0:len(A)//2]
    C = A[len(A)//2:]

 return (B,C)

나는 파이썬 3에서 int 나누기를 강제하기 위해 이중 슬래시가 필요했다. 왜냐하면 원래의 게시물은 wysiwyg가 Opera에서 파단되었지만 어떤 이유로 든 정확했다.


그것은 이상한 len (A)를 처리하지 않습니다-당신은 그것에 대한 해결책이 있습니까?
N997

6

배열을 더 작은 크기의 배열로 분할하는보다 일반적인 경우에 대한 공식적인 파이썬 저장소가 있습니다 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 doc 페이지 에서 가져온 것 입니다.


6

목록 슬라이싱 사용 . 문법은 기본적으로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( //정수 나누기 3//2 will give the floored result of-1 , instead of the invalid list index of1.5`)로 슬라이스하십시오.

>>> i[:len(i)//2]
[0, 1, 2]

.. 그리고 값을 바꾸어 후반부를 얻습니다.

>>> i[len(i)//2:]
[3, 4, 5]

이상한 len 목록은
어떻습니까

@ N997 코드는 여전히 작동합니다. 각 목록에서 다른 수의 항목으로 끝납니다. 그래서 목록이 말하는 세 가지 항목 긴, 결과가 그렇게 나누기 연산자 바닥 3//2제공 1, 당신은 얻을 i[:1]당신을 제공하는 [0]과 및 i[1:]제공하는[1, 2]
DBR

3

큰 목록이 있다면 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@Bede Constantinides 덕분에


3

10 년 후. 나는 생각했다-왜 다른 것을 추가하지 않는가 :

arr = 'Some random string' * 10; n = 4
print([arr[e:e+n] for e in range(0,len(arr),n)])

2

위의 답변은 다소 정확하지만 배열의 크기를 2로 나눌 수 없으면, 결과 a / 2가 이상하고 파이썬 3.0에서는 부동이고 이전 버전에서는 from __future__ import division스크립트 시작 부분에 지정 하십시오. 어떤 경우에도 정수 나누기, 즉 a // 2코드의 "앞으로"호환성을 얻으려면 더 나은 방법 입니다.



0

@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)

0
#for python 3
    A = [0,1,2,3,4,5]
    l = len(A)/2
    B = A[:int(l)]
    C = A[int(l):]       

0

2020 년에이 문제에 대한 또 다른 취지 ... 문제의 일반화가 있습니다. 나는 '리스트를 반으로 나누는 것'을로 해석합니다. (즉, 두 개의 목록 만 있고 홀수 하나 등의 경우 세 번째 배열로의 유출은 없을 것입니다). 예를 들어 배열 길이가 19이고 // 연산자를 사용하여 2로 나누면 9가 주어지면 길이 9의 배열 두 개와 길이 1의 배열 하나 (세 번째)가 생깁니다 (총 3 개의 배열). 일반적인 솔루션으로 항상 두 배열을 제공하려면 길이가 같지 않은 두 배열의 결과에 만족한다고 가정합니다 (하나는 다른 것보다 길다). 그리고 주문이 혼합되어 있다고 가정합니다 (이 경우 대체).

"""
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 행에서 시도했으며 몇 초 안에 끝납니다.

내 두 센트.

감사!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.