2017-12-20 10 views
3

私はPythonの初心者であり、短いリストの値で条件を満たすときに単純にリストの値を置き換えようとしています。例えばリスト要素を短いリストの値で条件付きで置き換えよう

list1 = [1,0,1,0,1,0] 
list2 = [1,2,3] 

私が欲しいの出力は次のようになります。

list1 = [1,1,1,2,1,3] 

私はカウンターでループを使用することができます。

counter = 0 
for i, j in enumerate(list1): 
    if j == 1: 
     list1[i] = list2[counter] 
     counter += 1 

しかし、これはそう何かのために非効率ですシンプルなので、リストの理解でこれを行う方法があると思います。

[list2[i] if j == 0 else j for i,j in enumerate(list1)] 

(ただし、リストの長さが異なるために失敗します)。

ベースpythonでこれを行う他の簡潔な方法は、おそらくmapまたはfilterを使用していますか?

+1

短いコードは必ずしも効率的なコードではありません。これがコードゴルフの挑戦でない限り、私はあなたが持っている解決策に何が間違っているのか見当たりません。 – mypetlion

+0

良い点ですが、私はこのタイプの操作を他の言語(論理インデックスを使用することができる)で多く使用していると思いますし、入力の容易さの点で似たようなものを探しています。 –

答えて

7

あなたは短いリストから作られたイテレータを使用して、ちょうど理解してそれにnextを呼び出すことができます。十分な充填材要素が存在しない場合は、nextにデフォルト値を提供することができます

list1 = [1, 0, 1, 0, 1, 0] 
list2 = [1, 2, 3] 

it2 = iter(list2) 

[x if x != 0 else next(it2) for x in list1] 
# [1, 1, 1, 2, 1, 3] 

注:

1

あなたはこれを試すことができます。

list1 = [1,0,1,0,1,0] 
list2 = [1,2,3] 
new_list = [list2[list1[:i].count(a)] if a != 1 else a for i, a in enumerate(list1)] 

出力:

[1, 1, 1, 2, 1, 3] 
3

のようなものを試してみてください:

[x if x else list2.pop(0) for x in list1] 

注これはlist2からアイテムを削除します。

+2

これがうまくいく間、 'pop(0)'はすべて 'O(N)'であることに注意してください。 – schwobaseggl

+0

@schwobaseggl素敵なキャッチ。 – Galen

+0

あなたはあらかじめリストを逆にしてから、 'pop()'を呼び出すことができると思います。しかし、リストを逆にすることは問題ではない、 'O(N)'です。 – RoadRunner

1

あなたがmap()を使用したい場合は、この試みることができる:

from collections import deque 

list1 = [1,0,1,0,1,0] 
list2 = [1,2,3] 

queue = deque(list2) 

result = list(map(lambda x : x if x else queue.popleft(), list1)) 

print(result) 

出力する:

[1, 1, 1, 2, 1, 3] 

注:を私ができるように、スタック/キューデータ構造、collections.dequeを使用しますpop(0)の代わりにO(n)の正面からのO(1)popleft()を使用してください。このライブラリを使用しない場合は、あらかじめlist2を逆転してpop()O(1))と呼び出してください。

関連する問題