使用.txt中的列表时的键错误,但不是

时间:2015-03-10 04:27:25

标签: python

我正在尝试使用包含可能单词的文本文件制作带素数的anagram解算器。我将文本文件拆分为单词列表,但我不断收到“关键错误:A”

此代码有效:

alpha_prime = {
    'p': 59, 
    'y': 101, 
    's': 71, 
    'o': 53, 
    'r': 67, 
    'q': 61, 
    'm': 43,
    'i': 29, 
    'f': 17, 
    'k': 37, 
    'a': 3, 
    'g': 19, 
    'c': 7, 
    'l': 41, 
    'd': 11, 
    'x': 97, 
    'e': 13, 
    'v': 83, 
    'w': 89, 
    'u': 79, 
    't': 73, 
    'z': 103, 
    'n': 47, 
    'j': 31, 
    'h': 23, 
    'b': 5
}

split_words = ['hello', 'mexico', 'father', 'john']

dic = {}

sum = 1
for i in split_words:
    list = [i]
    for x in list:
        for y in x:
            sum = sum * int(alpha_prime[y])
        dic[x] = sum

print(dic)

但这不是

alpha_prime = {
    'p': 59, 
    'y': 101, 
    's': 71, 
    'o': 53, 
    'r': 67, 
    'q': 61, 
    'm': 43,
    'i': 29, 
    'f': 17, 
    'k': 37, 
    'a': 3, 
    'g': 19, 
    'c': 7, 
    'l': 41, 
    'd': 11, 
    'x': 97, 
    'e': 13, 
    'v': 83, 
    'w': 89, 
    'u': 79, 
    't': 73, 
    'z': 103, 
    'n': 47, 
    'j': 31, 
    'h': 23, 
    'b': 5
}

words = open('words.txt', 'r')
words = words.read()
split_words = list(words.split())
dic = {}

sum = 1
for i in split_words: 
    new = [i]
    for x in new:
        for y in x:
            sum = sum * int(alpha_prime[y])
        dic[x] = sum

print(dic)

即使输入看起来是相同的格式,它也会给出KeyError:'A'。这是words.txt

的一个例子
A
a
aa
aal
aalii
aam
Aani
aardvark
aardwolf
Aaron
Aaronic

2 个答案:

答案 0 :(得分:1)

正如jedwards所说,'A'不是alpha_prime dict中的密钥,您可以将所有字符转换为小写并使用python dict get方法获取默认值:

words = open('words.txt', 'r')
words = words.read()
split_words = list(words.split())
dic = {}

sum = 1
for w in split_words: 
    for c in w:
        # Converting lo lower_case and retrieving '1' as default value
        sum *= int(alpha_prime.get(c.lower(), 1))
    dic[w] = sum

print(dic)

此外,您正在使用单词执行额外循环:list = [i]只包含一个单词,并且:for x in list:只会迭代一次。你正在尝试做的是检查每个单词的每个字符,你只需要两个循环,因为我把它放在我的代码上。

答案 1 :(得分:0)

这是另一个很好的方法

import string
import itertools

TEST_INPUT = """a
A
something
thingsome
elsewhere
elsewhen
foobar
baforo"""
TEST_ANSWERS = [False, True, False, True]

def is_anagram(a, b):
    primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
              59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
              127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181,
              191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241]
    letters = string.ascii_uppercase + string.ascii_lowercase + " "
    assert len(primes) == len(letters)
    mapping = dict(zip(letters,  primes))

    def product(*args):
        """functools.reduce(operator.mul, *args)

        product([2,3,4]) = 24
        product(5,6,7) = 350
        product([2,3], 4) --> ValueError"""
        product = 1
        if len(args) == 1 and hasattr(args, '__iter__'):
            lst = args
            for num in lst:
                product *= num
        else:
            for arg in args:
                product *= num
        return product

    return product(map(mapping.get, a)) == product(map(mapping.get, b))
    # also equal to:
    # product([mapping[ch] for ch in a]) == product([mapping[ch] for ch in b])

if __name__ == "__main__":

    def pairwise(iterable):
        cur,nxt = itertools.tee(iterable)
        next(nxt)
        return zip(cur,nxt)

    for a_b, answer in zip(pairwise(TEST_INPUT), TEST_ANSWERS):
        a, b = a_b
        assert is_anagram(a,b) == answer

但老实说,正常的做法是:

from collections import Counter

def is_anagram(a, b):
    return Counter(a) == Counter(b)