2013-12-15 3 views
0

약간의 python newb가 내 코드가 예상 된 결과를 제공하지 않는 이유를 알아 내려고 여기에 있습니다. 먼저 코드 :이 기능에Python itertools 순열이 인덱스 비교로 결과를 좁히고 예상대로 작동하지 않습니다.

from itertools import permutations 

word_list = ['eggs', ',', 'bacon', ',', 'chicken', ',', 'cheese', 'and', 'tomatoes'] 
grammar_list = ['NOUN', ',', 'NOUN', ',', 'NOUN', ',', 'NOUN', 'AND', 'NOUN'] 

def permute_nouns(): 
    permuted_list = [] 
    comma_AND_indices = [index for index, p in enumerate(grammar_list) if p == "," or p == "AND"] 
    # so 'comma_AND_indices' = [1, 3, 5, 7] 

    for perm in permutations(word_list): 
     observed_comma_AND_indices = [index for index, p in enumerate(perm) if p == "," or p == "and"] 
     if comma_AND_indices == observed_comma_AND_indices: 
      # what goes wrong here? not matches from list compare above still get appended below. 
      permuted_list.append(perm) 

    print permuted_list 

permute_nouns() 

나는 word_list의 순열을 생성하기 위해 itertools 순열 방법을 사용하고 있습니다. 그러나, 나는 모든 순열을 원하지 않는다. 쉼표와 단어 '와'가 원래 위치/색인을 그대로 유지하고 word_list에있는 순열 만 원하고 permuted_list에 추가하면됩니다.

내가 원하지 않는 순열을 걸러 내기 위해 코드 라인 if comma_AND_indices == observed_comma_AND_indices:을 사용하고 있지만 제대로 작동하지 않고 그 이유를 이해할 수 없습니다. permuted_list을 인쇄 할 때 쉼표와 '와'는 보존되지 않지만 모든 순열이 추가된다는 것을 알았습니다.

(기능에 grammar_list을 사용하여 귀찮게 왜 궁금 수 있지만, 여기 코드는 grammar_list이 역할을하는 약간 더 큰 스크립트의 일부입니다)

어떤 도움 것은이 감사에 빛을 넣어 .

대런

편집 : 당신이 더 간결 product()와 빠른 동일한 목록을 생성 할 수이기는하지만

[('eggs', ',', 'bacon', ',', 'chicken', ',', 'cheese', 'and', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'chicken', ',', 'tomatoes', 'and', 'cheese'), ('eggs', ',', 'bacon', ',', 'chicken', 'and', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'chicken', 'and', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'bacon', ',', 'cheese', ',', 'chicken', 'and', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'cheese', ',', 'tomatoes', 'and', 'chicken'), ('eggs', ',', 'bacon', ',', 'cheese', 'and', 'chicken', ',', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'cheese', 'and', 'tomatoes', ',', 'chicken'), ('eggs', ',', 'bacon', ',', 'tomatoes', ',', 'chicken', 'and', 'cheese'), ('eggs', ',', 'bacon', ',', 'tomatoes', ',', 'cheese', 'and', 'chicken'), ('eggs', ',', 'bacon', ',', 'tomatoes', 'and', 'chicken', ',', 'cheese'), ('eggs', ',', 'bacon', ',', 'tomatoes', 'and', 'cheese', ',', 'chicken'), ('eggs', ',', 'bacon', ',', 'chicken', ',', 'cheese', 'and', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'chicken', ',', 'tomatoes', 'and', 'cheese'), ('eggs', ',', 'bacon', ',', 'chicken', 'and', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'chicken', 'and', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'bacon', ',', 'cheese', ',', 'chicken', 'and', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'cheese', ',', 'tomatoes', 'and', 'chicken'), ('eggs', ',', 'bacon', ',', 'cheese', 'and', 'chicken', ',', 'tomatoes'), ('eggs', ',', 'bacon', ',', 'cheese', 'and', 'tomatoes', ',', 'chicken'), ('eggs', ',', 'bacon', ',', 'tomatoes', ',', 'chicken', 'and', 'cheese'), ('eggs', ',', 'bacon', ',', 'tomatoes', ',', 'cheese', 'and', 'chicken'), ('eggs', ',', 'bacon', ',', 'tomatoes', 'and', 'chicken', ',', 'cheese'), ('eggs', ',', 'bacon', ',', 'tomatoes', 'and', 'cheese', ',', 'chicken'), ('eggs', ',', 'bacon', 'and', 'chicken', ',', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'bacon', 'and', 'chicken', ',', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'bacon', 'and', 'chicken', ',', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'bacon', 'and', 'chicken', ',', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'bacon', 'and', 'cheese', ',', 'chicken', ',', 'tomatoes'), ('eggs', ',', 'bacon', 'and', 'cheese', ',', 'tomatoes', ',', 'chicken'), ('eggs', ',', 'bacon', 'and', 'cheese', ',', 'chicken', ',', 'tomatoes'), ('eggs', ',', 'bacon', 'and', 'cheese', ',', 'tomatoes', ',', 'chicken'), ('eggs', ',', 'bacon', 'and', 'tomatoes', ',', 'chicken', ',', 'cheese'), ('eggs', ',', 'bacon', 'and', 'tomatoes', ',', 'cheese', ',', 'chicken'), ('eggs', ',', 'bacon', 'and', 'tomatoes', ',', 'chicken', ',', 'cheese'), ('eggs', ',', 'bacon', 'and', 'tomatoes', ',', 'cheese', ',', 'chicken'), ('eggs', ',', 'chicken', ',', 'bacon', ',', 'cheese', 'and', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'bacon', ',', 'tomatoes', 'and', 'cheese'), ('eggs', ',', 'chicken', ',', 'bacon', 'and', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'bacon', 'and', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'chicken', ',', 'cheese', ',', 'bacon', 'and', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'cheese', ',', 'tomatoes', 'and', 'bacon'), ('eggs', ',', 'chicken', ',', 'cheese', 'and', 'bacon', ',', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'cheese', 'and', 'tomatoes', ',', 'bacon'), ('eggs', ',', 'chicken', ',', 'tomatoes', ',', 'bacon', 'and', 'cheese'), ('eggs', ',', 'chicken', ',', 'tomatoes', ',', 'cheese', 'and', 'bacon'), ('eggs', ',', 'chicken', ',', 'tomatoes', 'and', 'bacon', ',', 'cheese'), ('eggs', ',', 'chicken', ',', 'tomatoes', 'and', 'cheese', ',', 'bacon'), ('eggs', ',', 'chicken', ',', 'bacon', ',', 'cheese', 'and', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'bacon', ',', 'tomatoes', 'and', 'cheese'), ('eggs', ',', 'chicken', ',', 'bacon', 'and', 'cheese', ',', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'bacon', 'and', 'tomatoes', ',', 'cheese'), ('eggs', ',', 'chicken', ',', 'cheese', ',', 'bacon', 'and', 'tomatoes'), ('eggs', ',', 'chicken', ',', 'cheese', ',', 'tomatoes', 'and', 'bacon'), ('eggs', ',', 'chicken', ',', 'cheese', 'and', 'bacon', ',', 'tomatoes'), 
+1

왜 쉼표와 'AND'를 제거하지 않습니까? 더 효율적입니다. – thefourtheye

+0

문제점을 재현 할 수 없습니다. 귀하의 기준과 일치하는 2880 개의 버전과 362880 개의 전체 순열이 있습니다. –

+0

예상 출력물의 일부를 게시 하시겠습니까? –

답변

1

귀하의 코드가 잘 작동 : 다음 날 위해 인쇄 무엇의 샘플입니다 여기에서 [','] + 3 + ['and'][w for w in word_list if w not in (',', 'and')]의 순열의 동일한 120 * 24 = 2880 조합을 생성합니다.

결과가 120 개 밖에 없다면 출력에 3 쉼표와 단어 'and'의 순서를 테스트하지 않는다는 것을 잊고 있습니다. 즉

>>> len(list(permutations([','] * 3 + ['and']))) 
24 

, 당신은 3 개 쉼표와 다른 위치에있는 단어 and와 문장의 24 개 변동을 생산하고 바로 명사의 특정 순열 : 허용이 목록의 24 가지 순열이있다. 명사의 단지 120 개 조합을 생산하기 위해

은 : 중복이 중요하지 않은 경우

nouns = [w for w in word_list if w not in (',', 'and')] 
grammar = [w for w in word_list if w in (',', 'and')] 
result = [] 
for perm in permutations(nouns): 
    result.append([w for word, g in map(None, perm, grammar) for w in (word, g) if w is not None]) 
+0

Martijn, 고맙습니다. –

1

, 당신은 단지 itertools.product 사용했습니다 수 : 인쇄 어느

for words in itertools.product(*(['a'], ['big', 'fat'], ['dog', 'house'])): 
    print(' '.join(words)) 

:

a big dog 
a big house 
a fat dog 
a fat house 

하지만 그렇게하기 때문에 조금 더 복잡한 작업을해야합니다.

import itertools 
import collections 

grammar = ['NOUN', ',', 'NOUN', ',', 'NOUN', ',', 'NOUN', 'AND', 'NOUN'] 
parts_of_speech = { 
    'NOUN': ['eggs', 'bacon', 'chicken', 'cheese', 'tomatoes'], 
    'AND': ['and'], 
    ',': [','] 
} 

def partial_sentences(words, indices, sentence_length): 
    if len(indices) > len(words): 
     orderings = itertools.product(words, repeat=len(indices)) 
    else: 
     orderings = itertools.permutations(words, len(indices)) 

    for words in orderings: 
     sentence = [None] * sentence_length 

     for index, word in zip(indices, words): 
      sentence[index] = word 

     yield sentence 

def pos_stacks(parts_of_speech, grammar): 
    positions = collections.defaultdict(list) 

    for index, pos in enumerate(grammar): 
     positions[pos].append(index) 

    for pos, indices in positions.items(): 
     yield partial_sentences(parts_of_speech[pos], indices, len(grammar)) 

for result in itertools.product(*pos_stacks(parts_of_speech, grammar)): 
    sentence = [next(itertools.ifilter(bool, words)) for words in zip(*result)] 

    print(sentence) 

본질적 그 적절한 위치에서 단어의 모든 가능한 순서 부를 작성은 모두 함께 품사 및 "스택"문장을 루핑.