1

如何在 while 循环中使用 for 循环?这是我的代码:

def avoids(word,forbidden):
    for fl in forbidden:
        for letter in word:
            if letter == fl:
                return False
    return True

fin= open('words.txt')
u=97
v=97
w=97
x=97
y=97
minim=100
while u <= 122:
    while v <= 122:
        while w <= 122:
            while x <= 122:
                while y <= 122:
                    count=0
                    for line in fin:
                        word = line.strip()
                        if avoids(word,chr(u)+chr(v)+chr(w)+chr(x)+chr(y)):
                            #print(word)
                            count+=1
                            #print((100/113809)*count)
                    if (100/113809)*count<minim:
                        print(count)
                        minim=(100/113809)*count
                        print(minim,chr(u)+chr(v)+chr(w)+chr(x)+chr(y))
                    y+=1
                y=97
                x+=1
            x=97
            w+=1
        w=97
        v+=1
    v=97
    u+=1

它只执行一次 for 循环。我可以将 fin= open('words.txt') 放在最新的 while 语句中,但随后程序变得非常缓慢且几乎无法使用。我能做什么?(不是我不想使用列表等)

4

3 回答 3

5

它只执行一次 for 循环的原因是您在 for 循环的第一次迭代期间耗尽了为“words.txt”文件创建的缓冲区。

如果您想多次浏览该文件中的单词,则每次都需要重新打开它(正如您所指出的,这会产生很多开销)。

或者,将该文件读入列表,然后运行该列表的 while/for-loop 结构。

IE

fin= open('words.txt')
wordList = fin.readlines()
u=97
v=97
...
for line in wordList
...
于 2013-06-28T13:39:24.860 回答
1

您的代码看起来不会像这样缩进:

from string import ascii_lowercase
from itertools import product

for u, v, w, x, y in product(ascii_lowercase, repeat=5):
    ...

我不确定该avoids()功能应该做什么。目前的形式不太可能有用。你测试过吗?

也许你的意图是这样的

def avoids(word, forbidden):
    for fl, letter in zip(forbidden, word):
        if letter == fl:
            return False
    return True

但很难想象这会有什么用处。逻辑似乎仍然错误

于 2013-06-28T13:58:09.283 回答
0

您可以比根据文件更快地根据列表检查单词,因为它跳过了读取和写入开销。可以使用列表推导快速形成此列表。

import string
chars = string.uppercase
word_list = [''.join((a,b,c,d,e)) for a in chars for b in chars for c in chars
                                  for d in chars for e in chars]

'dkbke'.upper() in word_list
>>> True

你可以想出剩下的,因为我不确定你想用它做什么。

编辑:正如 gnibbler 刚刚教我的那样,以上内容并缩短使用

from itertools import product
from string import uppercase as chars

words = [''.join((a,b,c,d,e)) for a, b, c, d, e in product(chars, repeat=5)]

'dkbke'.upper() in words
>>> True

注意:至于学习不熟悉的东西,请尝试使用__doc__它来学习或只是玩它。例子:

product.__doc__
>>> product(*iterables) --> product object

Cartesian product of input iterables.  
Equivalent to nested for-loops.

For example, product(A, B) returns the same as:  
((x,y) for x in A for y in B).

The leftmost iterators are in the outermost for-loop, so the output tuples
cycle in a manner similar to an odometer (with the rightmost element changing
on every iteration).

To compute the product of an iterable with itself,
specify the number of repetitions with the optional repeat keyword argument.
For example,
product(A, repeat=4) means the same as product(A, A, A, A).

product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)
product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...

''.join.__doc__
>>> S.join(iterable) -> string

Return a string which is the concatenation of the strings in the
iterable.  The separator between elements is S.

''.join(['a','b','c'])
>>> 'abc'
'-'.join(['a','b','c'])
>>> 'a-b-c'
于 2013-06-28T16:07:07.507 回答