程序使用排列()来搜索文件中的所有单词

时间:2018-03-30 08:16:01

标签: python-3.x permutation

这是加扰文件中单词的功能

import itertools as it  
import random as rdm  

def get_permuted_lines(word_list):
    '''this function takes a list of all the words in the file in order they appear in the file and returns another list having all the scrumbled words in the same order they appear in the file'''  
    #final list is the list that will hold all the scrumbled words  
    final_list=[]  
    for word in word_list:  
        #words having length<=3 should not be scrumbled  
        if len(word)<=3:     
            final_list.append(word)  
        else:  
            if len(word)==4 and (word.endswith('.') or word.endswith(',')):  
                final_list.append(word)   
            elif len(word)==5 and word.endswith('\n'):  
                final_list.append(word)
            else:
                #if a line endswith ,
                if word.endswith(',\n'):
                    first_letter, *middle_letters, last_letter = 
                    word[0],word[1:-3],word[-3:len(word)]
                    perm_list = list(it.permutations(middle_letters, len(middle_letters)))
                    join_tup_words=[''.join(tup) for tup in perm_list]
                    final_list.append(first_letter+ join_tup_words[rdm.randint(0,len(join_tup_words)-1)]+last_letter)

                #if a line endswith .
                elif word.endswith('.\n'):
                    first_letter, *middle_letters, last_letter = word[0],word[1:-3],word[-3:len(word)]
                    perm_list= list(it.permutations(middle_letters, len(middle_letters)))
                    join_tup_words= [''.join(tup) for tup in perm_list]
                    final_list.append(first_letter+ join_tup_words[rdm.randint(0,len(join_tup_words)-1)]+last_letter)

                #for remaining words
                else:
                    first_letter, *middle_letters, last_letter=word
                    perm_list= list(it.permutations(middle_letters,len(middle_letters)))
                    join_tup_words=[''.join(tup) for tup in perm_list]
                    final_list.append(first_letter+ join_tup_words[rdm.randint(0,len(join_tup_words)-1)]+last_letter)

    return final_list

def read_write(fname):
    '''here we read from the file fname and write to a new file called fname + Scrumble.txt after creating it'''
    with  open(fname,'r') as f:
        lines=f.read()
    #getting a list of scrumbled words in order it appears in the file
    permuted_words=get_permuted_lines(lines.split(' '))

    #joining all the words to form lines
    join_words_list=' '.join(permuted_words)

    #creating a new file with the name (fname + scrumble.txt)
    new_file=fname[:-4]+'Scrumble.txt'  

    with open(new_file,'w') as f:
        f.write(join_words_list)

    with open(new_file,'r') as f:
        print(f.read())


if __name__=='__main__':
    '''getting the file name and passing it for readiing its content'''  

    #file_name is the name of the file we want to scramble
    file_name =input('enter the file_name: ')  
    read_write(file_name)  

我试过用re和随机模块尝试相同的程序,工作正常。也只使用随机模块完成任务。但是使用itertools.permutations()仅适用于行数较少(比如3)但不多行的文件。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

使用排列,你手头有一个组合爆炸。你的文本可能有一些长话:

from itertools import permutations
from datetime import datetime, timedelta

for n in range (1,15):
    g = ''.join("k"*n) 
    start = datetime.now()
    print()
    print( f' "{g}" feed to permutations leads to {len(list(permutations(g)))} results taking {(datetime.now()-start).total_seconds() * 1000} ms')

输出:

 "k" feed to permutations leads to 1 results taking 0.0 ms    
 "kk" feed to permutations leads to 2 results taking 0.0 ms    
 "kkk" feed to permutations leads to 6 results taking 0.0 ms    
 "kkkk" feed to permutations leads to 24 results taking 0.0 ms    

 <snipp>

 "kkkkkkkkk" feed to permutations leads to 362880 results taking 78.126 ms    
 "kkkkkkkkkk" feed to permutations leads to 3628800 results taking 703.131 ms    
 "kkkkkkkkkkk" feed to permutations leads to 39916800 results taking 8920.826 ms
 ... laptop freezes ...

对我而言,它长约12个字符。

如何避免它:不要使用排列 - 使用简单的随机播放:

import random

def removeSpaces(textList):
    return ' '.join(textList)  

def addSpaces(text): 
    return text.split(" ")

def needsScrambling(word):
    stripped = word.strip(",.?!")
    return len(stripped) > 3 and stripped.isalpha() 

def scramble(words):
    def scrambleWord(oneWord):
        prev = ""
        suff = ""
        if oneWord[0] in ",.?!":
            prev = oneWord[0]
            oneWord = oneWord[1:]

        if oneWord[-1] in ",.?!\n":
            suff = oneWord[-1]
            oneWord = oneWord[:-1]

        return ''.join([prev, oneWord[0], *random.sample(oneWord[1:-1], k=len(oneWord)-2),oneWord[-1],suff])
    return [ scrambleWord(w) if needsScrambling(w) else w for w in words]

def doIt(t):
    return removeSpaces(scramble(addSpaces(t)))

demoText = "Non eram nescius, Brute, cum, quae summis ingeniis exquisitaque doctrina philosophi"      + ' \n' +    \
"Graeco sermone tractavissent, ea Latinis litteris mandaremus, fore ut hic noster labor in varias"    + ' \n' +    \
"reprehensiones incurreret. nam quibusdam, et iis quidem non admodum indoctis, totum hoc displicet"   + ' \n' +    \
"philosophari. quidam autem non tam id reprehendunt, si remissius agatur, sed tantum studium tamque"  + ' \n' +    \
"multam operam ponendam in eo non arbitrantur. erunt etiam, et ii quidem eruditi Graecis litteris,"   + ' \n' +    \
"contemnentes Latinas, qui se dicant in Graecis legendis operam malle consumere. postremo aliquos"    + ' \n' +    \
"futuros suspicor, qui me ad alias litteras vocent, genus hoc scribendi, etsi sit elegans, personae"  + ' \n' +    \
"tamen et dignitatis esse negent."                                                                    + ' \n\n' +  \
"[2] Contra quos omnis dicendum breviter existimo. Quamquam philosophiae quidem vituperatoribus"      + ' \n' +  \
"satis responsum est eo libro, quo a nobis philosophia defensa et collaudata est, cum esset"          + ' \n' +  \
"accusata et vituperata ab Hortensio. qui liber cum et tibi probatus videretur et iis, quos"          + ' \n' +  \
"ego posse iudicare arbitrarer, plura suscepi veritus ne movere hominum studia viderer, retinere"     + ' \n' +  \
"non posse. Qui autem, si maxime hoc placeat, moderatius tamen id volunt fieri, difficilem"           + ' \n' +  \
"quandam temperantiam postulant in eo, quod semel admissum coerceri reprimique non potest, ut"        + ' \n' +  \
"propemodum iustioribus utamur illis, qui omnino avocent a philosophia, quam his, qui rebus"          + '\n' +  \
"infinitis modum constituant in reque eo meliore, quo maior sit, mediocritatem desiderent."           + '\n' +  \
"Source: https://la.wikisource.org/wiki/De_finibus_bonorum_et_malorum/Liber_Primus"

print(doIt(demoText))

输出:

Non eram niseucs, Bture, cum, quae siumms igeninis euaqusixtqie driocnta phlpoishoi 
Graeco srmenoe tevsricstanat, ea Lniatis liteirts mnurdeaams, fore ut hic noestr lbaor in varias 
reprehensiones icrenruert. nam qubsuidam, et iis qeuidm non audmdom itdnoics, toutm hoc dsieiplct 
philosophari. qaduim autem non tam id rneedrunepht, si rmesisuis auatgr, sed tntaum sutuidm tqmaue 
multam oaerpm pednnoam in eo non attuirranbr. eurnt etaim, et ii qideum edriuti Garceis liettris, 
contemnentes Laanits, qui se dinact in Gecrias lgednies orpeam mllae coermusne. psormeto aliuqos 
futuros sospciur, qui me ad ailas ltreatis vcnoet, geuns hoc sdrbcneii, etsi sit eaegnls, psneroae 
tamen et dgiainitts esse nenegt. 

[2] Conrta quos oinms dnuicedm betievrr esimtxio. Qumuqaam pooihhslipae qeduim vupaiteuoirbtrs 
satis rnupessom est eo libro, quo a noibs psiohoiplha densfea et cduoallata est, cum esest 
accusata et vtiaterupa ab Hirntseoo. qui liebr cum et tbii purotbas videertur et iis, qous 
ego posse irucdiae aaeribtrrr, pulra seuspci vterius ne mrovee hmiuonm sduita vdeerir, rntreeie 
non pssoe. Qui ateum, si mixmae hoc pclaaet, mairtdueos teamn id vnlout ferii, dciffeiilm 
quandam tnmreeaiptam pasounltt in eo, quod smeel aidsmsum cercroei rimriqepue non pteost, ut 
propemodum itriuosiubs uuamtr iills, qui omnino aocevnt a pshoihloipa, qaum his, qui rebus
infinitis mdoum caustinontt in rquee eo mierole, quo miaor sit, meretiicodatm desiderent.