2011-08-01 6 views
1

이상한 이유로 List Comprehensions 및 List Comprehensions만을 사용하여 10 개의 난수를 더 많이 생성한다고 가정 해 봅니다. 0.5 이상. 문제의 "10 개 임의의 숫자"의 경우 우리가 사용하는 것 :무작위 값을 기준으로 필터링하여 목록 이해력을 사용하여 균일하게 분포 된 임의의 부동 소수점을 생성합니다.

samples = [ random.random() for x in range(10) ] 

을 이제 하나의 LC를 사용하여 구현하는 것이 어떻게 "보다 큰 0.5"에 대한?

samples = [ random.random() for x in range(10) if ??? ] 
+1

음, 특정 경우에, 당신이 단지 것'[random.random() + 0.5 (10 : 그러나 오히려 사용 itertools보다, 나는를 내장 iter 기능을 사용합니다)]'나는 그것이 당신이 묻고있는 것이라고 생각하지 않는다! :) –

+0

죄송합니다 ... 10 이하의 임의의 숫자를 말해야합니다 :) 원래 게시물은 겸손한 운동으로 변경되지 않습니다. – Rodrogo

+0

"10 이하"로 0을 기꺼이 받아들입니까? –

답변

6

거부 ​​샘플링이라고하는 것은 무엇에 관한 설명이며 잘못된 생각입니다. 예를 들어, 숫자가 >0.999 인 경우 숫자가 이되도록 길이가 길어집니다.


가장 좋은 방법

이 수행하는 올바른 방법 등 CDF의 역수 (누적 밀도 함수)를 사용하고, [inverseCDF(random()) for _ in range(10)] 하 같은 다른 샘플링 기술을 사용하는 것이다. GaretJax이 시사하는 것처럼 귀하의 경우에는, 이것은 내가 당신의 의도는 지능형리스트의 전체 표현을 기반으로 필터를 촉진 할 수있는 한 생각

[0.5+random()/2 for _ in range(10)]


의도 일 것이다. (그것은 중요하지 않습니다하지만, 게으름에 대한보다 rathern 괄호 [...] 여기)이 경우, 다른 이해 내부에 반복자를 둘 것 :이 라인을 따라 더 나은 솔루션을 위해

[r for r in (random.random() for x in range(10)) if r>0.5] 

그 수 거절을 처리하려면 "목록 통합 기능이있는 솔루션"섹션이나 eryksun's answer을 참조하십시오. 발전기


솔루션 당신은 어떤 선형 범위에 대해이 작업을 수행 할 수 있습니다

(목록-이해 유일한 해결책은 아래 참조). 거부 기능이 임의로 복잡하다면 거부 샘플링을 수행하는 일반적인 방법은 다음과 같습니다. (다시, 아주 나쁜 생각은 당신이하고있는 효율성이 중요하지 않습니다 알고하지 않는 한.)

from random import random 
from itertools import * 

def randoms(): 
    while True: 
     yield random() 

def rejectionSample(pred, n): 
    return islice(filter(pred, randoms()), n) 

예 :

def rejectionSample(pred, n): 
    count = 0 
    while count<n: 
     r = random() 
     if pred(r): 
      yield r 
      count += 1 
:

>>> print(list(rejectionSample(lambda x:x>0.5))) 
[0.6656564857979361, 0.9850389778418555, 0.9607471536139308, 0.9191328900300356, 0.810783093197139] 

당신은 또한 같은 뭔가를 할 수 지능형리스트 만

를 가진 는

솔루션 당신은 단지 지능형리스트 를 사용하려면 이후 6,

그러나, 이것은 당신이 어떻게 든 이해의 while 루프를 포함해야합니다 귀하의 이해의 표현 부분은, 실패 할 수 을 의미합니다. 이것만으로도 하나의 람다 기능을 수행하는 것은 불가능하지만, 우리는 우리가 어떤 재귀/깨어나는 원시적 인, 예를 들면 ...

[next(filter(pred,randoms())) for _ in range(10)] 

가 (당신이 정말로 한 라이너를 원한다면 가지고 그것을 해낼 수 있습니다 목록 이해, randoms()(random() for _ in count())으로 다시 쓸 수 있습니다. 특정 분포에 대한 분석 역 누적 분포 함수를 쉽게 찾을 수 있으면이 방법은 필요하지 않습니다.


편집는 : 나는 그냥 ... 람다와 ... 그 뒤로 ... 그것은 ... 가능입니다 걸릴

나는 UPON 해방 분께 하나님 자비 무엇 공포하신 다른 사람이 보여준 것처럼 세계는 NOOOOOO

[ 
(lambda f:f(f,random()))(lambda self,r:r if r>0.5 else self(self,random())) 
for _ in range(10) 
] 
+0

randoms 함수를 이미 구현 한 경우 쉽게 필터링을 구현하거나 내 접근 방식을 사용하고 더 나은 가독성을 위해 다음/필터 구문을 다른 생성기로 분할 할 수 있습니다. – GaretJax

4

랜덤 특정 문제가 쉽게 다음과 같이 해결할 수 있습니다

samples = [ random.random()/2 + .5 for x in range(10) ] 

하지만 난 당신이 생성 된 항목에 대한 테스트를 실행하려는 당신이 질문은 특정 문제를 해결하기 위해 목표로 것 같아요 . 당신은 여러 지능형리스트, 또는 더 나은을 사용하는 반복의 수를 제한하는 발전기 및 지능형리스트를 사용하여이 작업을 수행하려면 : 첫 번째 발전기 사이에 다른 발전기 기반 필터를 삽입 할 수 있습니다

samples = (random.random() for x in range(10)) 
samples = [x for x in samples if x > .5] 

주와 마지막 목록 이해력. 이렇게하면 한 번에 원하는대로 할 수 있습니다. 이 주제에 대한 흥미로운 내용은 http://www.dabeaz.com/generators/http://www.dabeaz.com/coroutines/입니다 (두 번째 저자는 동시 처리 및 생성기를 사용하여 간단한 운영 체제를 구현 함).

이제이 코드는 정확히 10 개의 항목을 원한다는 사실을 설명하지 않습니다. 예를 찾아서 코드를 작성하고 편집 해 봅니다 (편집 : "10 이하"에 대한 귀하의 의견을 보았 기 때문에이 질문에 이미 답변했습니다 ... 어쨌든 10을 제공하는 해결책을 찾으려고합니다. 항목, 재미 :)).

편집 :

나는 다음과 같은 솔루션을 함께했다. 이은 (는) itertools 모듈을 사용하기 때문에 LC/발전기없는 순수 기반으로,하지만 난 그것을 게시 흥미로운 일이 될 것이지만 :

def iiter(): 
    while True: 
     yield None 
:

import itertools 
import random 

samples = (random.random() for _ in itertools.count()) 
samples = (x for x in samples if x > .5) 
samples = [next(samples) for _ in range(10)] 

비록, 당신은 쉽게 다음 코드로 itertools.count 기능을 대체 할 수

이 모든 것이 이해가되지 않습니다. 단순히 생성기를 직접 생성하여이 모든 생각없이 원하는 결과를 얻을 수 있지만 목록 이해 및 생성기는 내가 가장 좋아하는 파이썬 기능 중 두 가지입니다!

+0

* "이제이 코드는 정확히 10 개 항목을 원한다는 사실을 설명하지 않습니다."* 주요 문제인 것으로 보입니다. – ninjagecko

+0

@ninjagecko : 원래 질문에 대한 설명을 읽으면 이것이 주요 문제가 아님을 알 수 있습니다. 어쨌든이 문제를 해결하는 코드는 제 대답에도 포함되어 있습니다. – GaretJax

+0

@ ittoools.count()를 사용할 때 @GaretJax가 멈 춥니 다. itertools.count()를 시도했을 때 컴퓨터가 거의 멈추었습니까? 거친 것 중 하나는 파이썬 콘솔에서 자체적으로 실행했습니다. –

-2

나는 내가 기압 나와 함께 파이썬 수있는 기계를 가지고하지 않는 한 당신이 syntatically 정확하지 않을 수 있습니다

samples = [ x for x in range(10) if random.random() > 0.5 ] 

또는

samples = [ (lambda r: r > 0.5 and r or 0)(random.random()) for x in range(10) ] 

두 번째 의미 생각합니다.

편집 : - 나는 이것이 허용 대답을 가지고 알고 난 여전히 두 downvotes하지만 알고 :

samples = [(0.5 + (random.random() * 0.5)) for x in range(10)] 

당신에게 0 ~ 10 개 임의의 숫자를 제공합니다.5 및 1

1

내가 할 수있는 최선은, 기능을 필터링하는 샘플 생성기를 사용하는 것입니다. 범위에 _ 대한

>>> import random; random.seed(42) 

>>> sample = (x for x in iter(lambda:random.random(), 1) if x > 0.5) 
>>> samples = [next(sample) for _ in range(10)] 

>>> print(', '.join(format(s, '0.3f') for s in samples)) 
0.639, 0.736, 0.677, 0.892, 0.505, 0.650, 0.545, 0.589, 0.809, 0.806 
관련 문제