2016-03-30 10 views
2

ランダムなモジュールを使ってリストから文字列を抽出することはできますが、文字列の長さがxより大きい場合にのみ可能ですか?例えば基準を満たすリストからランダムな値を抽出しますか? Python

list_of_strings = ['Hello', 'Hello1' 'Hello2'] 

あなたがx = 5を設定し、コードのみlist_of_strings[1]list_of_strings[2]の間で 'を選択' されるだろうrandom.choice()を呼び出した場合。

len > xの値しか含まれていない2番目のリストを作成することができますが、この手順を実行しなくても可能かどうかを知りたいと思います。

random.choice([i for i in list_of_strings if len(i) > x]) 
+0

リストの理解? –

+0

IOW、ループを使用することは可能ですが、おそらく単なる理解力を使う方が良いでしょう。 –

+0

それほど確かではありませんが、理解はまた別のリストを作成しています。 – krato

答えて

4
random.choice([s for s in list_of_strings if len(s) > x]) 

それとも、このような何かを行うことができます:

+1

* "2番目のリストは、 len> xだが、このステップがなければ可能かどうかを知りたい」* – Christian

+0

条件を満たす要素があまりないと遅くなる。詳細は私の答えを見てください。 – arekolek

0

あなたはこれを行うことができます

while True: 
    choice = random.choice(list_of_strings) 
    if len(choice) > x: 
     return choice 

長いXよりもリスト内の文字列がある場合は、最初に確認する必要がありますそれ以外のコードは決して終わらないでしょう。

解決策のもう1つの可能性は、リザーバサンプリングを使用することです。これは、実行時間が制限されているという追加の利点があります。追加のリストを作成しません

+0

* "len> xの値だけを含む2番目のリストを作成することができますが、この手順を実行しなくても可能かどうかを知りたいと思います。" * – Christian

1

別の解決策:

from itertools import islice 
from random import randrange 

def choose_if(f, s): 
    return next(islice(filter(f, s), randrange(sum(map(f, s))), None)) 

choose_if(lambda x: len(x) > 5, list_of_strings) 

は、それがクリスチャンのソリューションよりもほぼ二倍遅いが判明します。これは、sを2回繰り返し、すべての要素にfを適用するためです。 2番目のリストを作成しないことから利益を上回るには高価です。

フランシスコのソリューションは、適切な要素を選択できなかった回数だけfを何度も適用するため、その10〜100倍高速になる可能性があります。ここでは、その関数の完全なバージョンです:

from random import choice 

def choose_if(f, s): 
    if any(filter(f, s)): 
    while True: 
     x = choice(s) 
     if f(x): return x 

クマを念頭に置いて、それは少数(1%未満)の要素が条件を満たしたときに悪化し始めます。 5000の要素が1つだけ良い場合は、リストの理解を使用する場合よりも5倍遅くなりました。

関連する問題