リストを小さなリストに分割(半分に分割)


150

Pythonリストを簡単に半分に分割する方法を探しています。

したがって、配列がある場合:

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
Python 3でint除算を強制する必要があります。//が必要です。
Stefan Kendall

4
素晴らしい解決策、ありがとう。Python3の80/20のような分数でも動作しますB = A[:(len(A) // 10) * 8] C = A[(len(A) // 10) * 8:]
Gergely M

87

もう少し一般的な解決策(「半分に」分割するだけでなく、必要なパーツの数を指定できます):

編集:奇数リストの長さを処理するようにポストを更新

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)

2
リストが均等に分割されない場合(例:split_list([1,2,3]、2))、これは実際にはwanted_pa​​rts + 1リストを返します。
ブライアン

3
私が考えるより良い方法は次のとおりです:length = len(alist); return [alist [i * length // Wanted_pa​​rts:(i + 1)* length // Wanted_pa​​rts] for i in range(wanted_pa​​rts)]。このようにして、可能な限り均等な分布を取得し、常に正確にWanted_Partsアイテムを取得します(Wanted_Parts> len(A)の場合は[]でパッドも)
Brian

2
こんにちは。「//」という記号はどういう意味ですか?
frazman

2
@Frazそれはインラインコメントとして意図されています。「// Wanted_Parts」および「// Wanted_Parts」を無視して、スクリプトを実行します。
PunjCoder

19
//整数除算を意味します。これらは、この作業を行う上で非常に重要であるため、除外しないでください。
Alphadelta14 2013年

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

n -事前定義された結果配列の長さ


1
これは私の状況ではうまくいきますが、各リストの最後のインデックスを1つおきに独自のリストに追加しています。説明するのは難しい。あなたが助けることができるなら返信してください、そして私はもっと説明します。
Mike Issa、2016

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))listそしてlengthsリストは同じ長さを有しています。jは交互です:5,4,5,4,5、そしてsplit関数は最初の2つの代替で機能します。つまりi、リストの最初を5と4で分割しますが、次の反復でそれを4,4で分割します。 1。:\詳細を説明したい場合は返信してください(新しい質問を投稿してください)
Mike Issa

15

注文を気にしない場合...

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

list[::2]リストの2番目の要素を0番目の要素から取得します。
list[1::2]最初の要素から開始して、リストの2番目ごとの要素を取得します。


4
組み込みのlistシャドウイングでargに慎重に名前を付けlist(...)ます。私はそれを避けるためによく見lstlist_使用しました。
テイラーエドミストン2017

3
これはほとんどのpythonicを感じます(間違った名前を無視して)
Tjorriemorrie


11

これは一般的な解決策です、arrをcount部分に分割してください

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

これはリストの順番を失います
Timmah '20

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

 return (B,C)

私はテストしましたが、Python 3でint除算を強制するにはダブルスラッシュが必要です。何らかの理由で、wysiwygがOperaで壊れましたが、私の元の投稿は正しかったです。


それは奇数のlen(A)を処理しません-そのための解決策はありますか?
N997

6

配列をサイズの小さい配列に分割する、より一般化されたケースの公式の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 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年後..私は思った-もう1つ追加してみませんか。

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

2

上記の回答は多かれ少なかれ正しいですが、配列のサイズが2で割り切れない場合、a / 2奇妙な結果として、Python 3.0ではフロートであり、以前のバージョンではfrom __future__ import divisionスクリプトの最初に指定します。いずれにせよa // 2、コードの「前方」互換性を得るために、整数除算を行う方がよいでしょう。


2

これは他のソリューションと似ていますが、少し高速です。

# 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:]

バイナリシフトの賢い使い方!
Janusz Skonieczny

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

2020年にこの問題についてもう1つ取り上げます...問題の一般化を次に示します。私は「リストを半分に分割する」を..と解釈します(つまり、2つのリストのみで、1つが奇数の場合の3番目の配列へのスピルオーバーはありません)。たとえば、配列の長さが19で、//演算子を使用して2で除算すると9が得られ、長さ9の2つの配列と長さ1の1つの配列(3番目)になる(合計で3つの配列)。常に2つの配列を与える一般的なソリューションが必要な場合は、長さが等しくない(一方が他方よりも長くなる)結果のデュオ配列に満足していると想定します。また、順序を混在させることもできます(この場合は交互)。

"""
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行)で試したところ、ほんの一瞬で終了しました。

ちょうど私の2セント。

ありがとう!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.