2017-10-12 5 views
0

リストへの(移動)ポインタをPythonの関数に渡すことは可能ですか?リストではなく関数にリストポインタを渡す

私は、リストのセクションを処理する再帰関数を持っています。リスト自体は変更されず、その中の「開始点」へのポインタだけが変更されます。私が遭遇した問題は、長いリストがメモリオーバーランでコードを殺したことでした。ここで

コードは次のとおりです。上記の例は不自然である

def trim(l): 
    print("list len= ", len(l)) 
    if len(l)!= 1: 
     trim(l[1:]) 
    else: 
     print("done") 

、私の実際のコードはリストだけをトリミングとは異なるものを行いますが、それはまた、移動開始ポインタを持っています。 100万個の整数のリストが10G RAMマシン上のメモリから吹き飛んだ。

アイデアを歓迎します。

+3

Pythonがポインタを持っていません。コピーを作成するスライスの代わりにインデックスを渡すことができます。また、オブジェクト指向プリミティブ配列を提供する 'numpy'の使用を検討することもできます。スライスはコピーではなくビューを作成します。また、組み込みの 'array'モジュールもあり、大きさの数値型の空間効率のよいプリミティブ配列を提供します。これらのアレイアプローチの両方は、桁違いの省スペースを提供するはずです。百万の64ビット整数は約8メガバイトです –

+1

['deque'](https://docs.python.org/3.6/library/collections.html#collections.deque)のデータ構造が役立つかもしれません。 (すべての要素の浅いコピーである)スライスを渡す代わりに、 'l.popleft()'を使って両端キューの先頭から要素を削除することができます。これは 'l'がリストであるとき' l.pop(0) 'のコピーコストを発生させません。 – trentcl

答えて

2

新しいリスト全体を渡すのではなく、インデックスを渡すだけでいいですか?

したがって、trim(l, 0)と呼び出し、リストの長さに対してインデックスを確認し、必要に応じてtrim(l, 1)に電話します。大規模データを扱う場合

def trim(l, idx): 
    print("list len = ", (len(l) - idx)) 
    if idx < (len(x) - 1): 
     trim(l, idx + 1) 
    else: 
     print("done") 
2

テールコール以外の再帰関数を使用してリストを反復処理すると、スタックオーバーフローやスタックサイズに関連するメモリ不足エラーが発生する可能性が高くなります。

私はこれを整数ポインタとfor-loopで書き直すことをお勧めします。これは、Pythonにテールコールの最適化がないようです。

は、ここであなたがやりたいと思っかもしれないものを推測です:

x = [0,0,0,0,0,1,2,3,4] 

def trim_leading_zero(l): 
    the_len = len(l) 
    start_i = 0 
    for i in xrange(the_len): 
    if l[i] != 0: 
     return l[i:] 

>>> trim_leading_zero(x) 
[1, 2, 3, 4] 

それは実際に行うためのものだ何をあなたのコードからも明らかではありません。実際にシーケンスを返そうとしているのであれば、メモリ内のシーケンス全体を保持する必要のないジェネレータを見たいかもしれません。

0

発電の代わりに、定期的なイテレータを使用しています。

def trim(l): 
    print("list len= ", len(l)) 
    pointer = 0 
    if len(l)!= 1: 
     yield l[pointer:] 
     pointer += 1 
    else: 
     print("done") 

x = [1, 2, 3, 4, 5, 6, 7, 8, 9] 

for i in trim(x): 
    print i 

# [1, 2, 3, 4, 5, 6, 7, 8, 9] 

ジェネレータは、時間でつのアイテムを生じ、処理する前に、まず全体のリストを作成避け、あなたがそれを必要とする何でもをさせます。リストを取得したい場合は、単にlist(trim(x))を実行してください。

yieldgeneratorsの偉大な説明がここにあります - What does the yield keyword do

関連する問題