通过函数运行文件

时间:2013-12-15 22:15:45

标签: python file function anagram

我正在尝试从当前文件创建一个包含anagrams行的新文件。

def Ana(str1, str2):
    str1_list = list(str1)
    str1_list.sort()
    str2_list = list(str2)
    str2_list.sort()
    return (str1_list == str2_list)

newerfile=open("ana.txt","w")
f = open("words.txt")
for word in f:
    s = str(word)
    for word2 in f:
        if word!=word2:
            if Ana(word, word2) is True:
                s += (' ') + str(word2)

if s!=str(word):
    newerfile.write(s)

以上是我当前的代码,但它给我的全部是一个空文件。经过一番实验后,我认为问题出现在第4行 - “if isAnagram(word,word2)if if:”

该功能对我所拥有的文件无效。我已经尝试了一个更基本的代码版本来测试一个单词的整个文件。由于'was'和'saw'这两个词在文件中,我应该得到那些,但没有任何东西被打印出来。

y = 'was'
for line in open('real_words.txt'):
    if isAnagram(line,'was') is True:
        y += (' ') + str(line)
print(y)

当我提供单词列表时,该功能正常工作,但不提供文件。任何帮助表示赞赏。

如果函数返回true,还有什么方法可以从文件中删除单词和所有字谜?

2 个答案:

答案 0 :(得分:2)

最好的数据结构是列表的字典,其中每个字符串的排序版本是关键字。共享该排序版本的每个单词都将进入列表。生成之后,只有一个单词的键进入文件中没有字谜的单词,而带有多个单词的键进入字谜文件。

from collections import defaultdict
words_by_sorted = defaultdict(list)
f = open("words.txt")
for line in f:
    word = line.strip() # remove the newline
    sorted_key = tuple(sorted(word))
    words_by_sorted[sorted_key].append(word)
f.close()
unanagrammed = open("unanagrammed.txt", "w")
anagrammed = open("anagrammed.txt", "w")
for words in words_by_sorted.itervalues():
    if len(words) == 1:
        unanagrammed.write(words[0] + '\n')
    else:
        anagrammed.write(' '.join(words) + '\n')
unanagrammed.close()
anagrammed.close()

这不会在任一文件中保持顺序。如果你需要这样做,你可以按照你第一次看到它们的顺序维护一个排序键的列表,或者使用一个有序的dict(并根据需要显式创建列表,而不是使用defaultdict)如果你'重新开始2.7。

它还会创建两个文件 - 您无法真正“将它们从旧文件中删除”,但如果您愿意,可以覆盖它。这种方法可以让您在删除输入之前更仔细地检查输出。

使用with语句打开文件也是一种很好的做法,但您的基本代码使用原始open,所以我坚持使用它。

答案 1 :(得分:0)

(假设words.txt是一个每行一个单词的文件,你试图找到这些单词的所有字符对并将它们打印到第二个文件,每行一对。)

您的代码似乎有两个问题:

  1. 当你for word in f使用迭代器时,使用for word2 in f使用相同的迭代器,即迭代器将在第一次迭代后耗尽环<!/ LI>
  2. 您似乎只在循环完成后写入文件,但s将始终只保留最后一对单词,因此您只需将该对写入该文件。 (可能只是缩进的问题。)
  3. 要获得两个单词的所有组合,最好使用itertools.combinations,有点像这样(未经测试的伪代码):

    words = infile.read().splitlines()
    for w1, w2 in itertools.combinations(words, 2):
         if isAnagram(w1, w2):
              outfile.write("%s %s" % (w1, w2))
    

    但是,每行只会写一个的字谜。如果你想把整个写成一行,我想你需要两个循环,就像你的代码一样。请记住,不要对两个循环使用相同的迭代器,例如首先将filt的内容放入列表中,然后将该列表用于循环。

    你也可以使用列表理解:

    words = infile.read().splitlines()
    for w1 in words:
        outfile.write(" ".join(w2 for w2 in words if isAnagram(w1, w2)))
    

    (请注意,这仍然不完美,因为线条将重复,对于组中的每个单词都会重复一次。但我相信你可以自己弄清楚其余部分。)