2010-11-22 5 views
2

간단하다면 사과하겠습니다 만, 지금 당분간은 찾고 있었지만 간단하고 효율적인 솔루션을 찾을 수 없습니다.검색 기준에 따라 파이썬 배열에서 무작위 요소를 반환합니다.

필자는 1과 0으로만 구성된 목록의 2 차원 파이썬 목록을 가지고 있습니다.

예 :와

[0,1], [1,1], [1,2], [2,0], or [2,2] 

:

나는 무작위로 반환 할
a=[[0,1,0],[0,1,1],[1,0,1]] 

, 내가 하나를 반환하려는이 경우 = 1. 임의의 요소의 인덱스 인 균등 확률.

구조의 모든 요소를 ​​반복하고 적절한 인덱스 목록을 컴파일 한 다음 random.choice (list)를 사용하여 무작위로 하나를 선택할 수 있습니다. 그러나 이것은 매우 느린 것으로 느껴지며 깔끔한 느낌이 들지 않습니다. , 더 접근하기위한 Pythonic 방식. 아마 20x20 배열을 위해이 작업을 수행 할 것이며 여러 번해야 할 것입니다. 그래서 가능한 한 효율적으로 할 수 있습니다.

도움과 조언을 미리 보내 주셔서 감사합니다.

+0

당신이 배열이 확실 사용, 확인하려면? 또는 목록 목록입니까? –

+0

"여러 번"동일한 배열에서 여러 번 또는 다른 배열을 수행하는 것을 의미합니까? – lijie

+0

죄송합니다, 목록 목록입니다. 내 실수. 나는 그 지위를 바로 잡을 것이다. – Scott

답변

2

내가 튜플의 목록을 생성 지능형리스트를 사용하십시오 (1 순위), 다음 random.choice :

from random import choice 

a = [[0,1,0],[0,1,1],[1,0,1]] 
mylist = [] 

[[mylist.append((i,j)) for j, x in enumerate(v) if x == 1] for i, v in enumerate(a)] 
print(choice(mylist)) 
+0

나는 완벽한 해결책을 찾았습니다. 감사합니다! 나는 그 라인을 따라 무언가를 생각하려고 노력했지만 파이썬은 그다지 중요하지 않았습니다. – Scott

+0

@Scott, StackOverflow에 오신 것을 환영합니다! 당신이이 대답을 좋아하는 것 같았다. StackOverflow에 대한 멋진 점 중 하나는 모든 사람이 올바르게 사용하면 스스로 개선된다는 것입니다. 가장 좋은 답변은 "선택"되어 투표됩니다. 이 사람이 마음에 드시면 답변자에게 보상 할뿐만 아니라 좋은 답변에 투표하면 사이트가 향상되고 질문에 대한 대답은 좋아집니다. – Crisfole

+0

@Cpfohl - 방금 등록하고 시도했지만 적어도 15 개의 평판이 필요하다고 말합니다. 나는 내가 초보자이기 때문에 이것이라고 생각한다. 그러나 만일 내가 할 수 있으면 나는 투표 할 것이다! – Scott

0

당신이 다시

def return_random(li): 
    item = random.choice(li) 
    if item == 1: #insert check here 
     return item 
    else: 
     return_random(li) 

편집 무작위가 아닌 경우 올바른 요소를 싶습니다 어떻게하면 당신은 random.choice 검사에서 결과를 얻을 때 : 감사

를 다시 모듈과의 혼동을 피하기 위해
+0

잘 사용 된're'를 변수로 사용해서는 안됩니다. 혼란 스러울 수 있습니다. – Danosaure

+0

고마워, 그게 정말 도움이되었고 나는 그런 식으로 생각하지 않았다. 한 가지 잠재적 인 문제는 때로는리스트가 1로 채워지는 경우가 있는데,이 방법은 매우 비효율적 일 수 있습니다. 그러나 실제로 코드를 실행하고 볼 때까지는 이것이 문제인지 여부를 알 수 없으므로 확실히 시도해 볼 수 있습니다. – Scott

+0

나중에 최적화에 대해 걱정할 것입니다. 항상 작동하는 프로그램을 최적화 할 수는 있지만 속도를 높이기가 어렵습니다. 실제로 처리하지 않습니다. –

1

난에 NumPy 배열을 사용합니다 이를 :

from numpy import array 
random_index = tuple(random.choice(array(array(a).nonzero()).T)) 

상점 바로 처음부터 NumPy와 배열에 데이터를,이 방법은 아마 당신이 목록의 목록과 함께 할 수있는 일보다 더 빨리 될 경우

.

동일한 데이터에 대해 많은 색인을 선택하려는 경우 더 빠른 접근 방법이 있습니다.

1

random.choice 목록에서 요소를 임의로 선택할 수 있으므로 목록 이해를 사용하여 요소가 1 인 색인 목록을 만든 다음 무작위로 색인 하나를 선택하면됩니다.

>>> a = [[0,1,0],[0,1,1],[1,0,1]] 
>>> [(x,y) for x in range(len(a)) for y in range(len(a[x])) if a[x][y] == 1] 
[(0, 1), (1, 1), (1, 2), (2, 0), (2, 2)] 

우리가 할 수있는 의미 :

>>> import random 
>>> random.choice([(x,y) for x in range(len(a)) for y in range(len(a[x])) if a[x][y] == 1]) 
(1, 1) 

이 여러 번 수행 될 경우 생성 인덱스의 목록을 캐시 가치가있을 수 있습니다

우리는 다음과 목록 이해를 사용할 수 있습니다 이해력에 의해 그리고 나서 그것을 여러 번 선택하는 것보다는 매번리스트 이해력을 계산하는 것입니다.

0

또 다른 아이디어는 데이터를 완전히 다른 방식으로 저장하는 것입니다. 목록 목록 대신 1 인 항목을 나타내는 인덱스 쌍 집합을 사용하십시오.당신의 예에서,이 0에 항목을 설정하려면

s.add((i, j)) 

를 사용

s = set((0, 1), (1, 1), (1, 2), (2, 0), (2, 2)) 

무작위로 인덱스 쌍을 선택하려면, 1 항목을 설정하려면

random.choice(list(s)) 

를 사용하는 것 , 사용

s.remove((i, j)) 

항목을 반전하려면 다음을 사용하십시오. 항목이 1이면

s.symmetric_difference_update([(i, j)]) 

(i, j) in s