如果在用户inpu中找到键,则从dictionary对象打印多个键和值

2024-06-16 12:36:07 发布

您现在位置:Python中文网/ 问答频道 /正文

*********已编辑*********

所以这是我代码的一个更完整的版本,正如一些人评论的那样。我需要它做的是打印在user_tweet属性中找到的任何键和相应的值,该属性是一个字符串160个或更少的字符。不幸的是,我能做的就是打印用户推文中最后一次出现的密钥。在

#Dictionary item

abb_dict = {
'lol': 'laughing out loud',
'bfn': 'bye for now',
'cuz': 'because',
'gtg': 'got to go',
'brb': 'be right back',
'nvm': 'nevermind',
'bff': 'best friends for ever',
'rofl': 'rolling on the floor laughing',
'omg': 'oh my god',}

user_choice = raw_input() ###Determines if user quits program


t_round = 0 #determines how many tweets have been decoded for exit message


while True:
    if user_choice == 'Q' or user_choice =='q': #quits program 
        break

#INPUT INTO user_tweet: omg shut up i gtg
    user_tweet = raw_input('Type a Tweet 160 Character or less').lower()

    if len(user_tweet) <= 160:
        for x in abb_dict:
            if x in user_tweet:
                print x , abb_dict[x]

#OUTPUT: gtg got to go

所以我遇到的问题是,它只打印最后一次出现的键和值。 不管我放了多少,它总是打印最后一个。在


Tags: togoforrawif属性dicttweet
3条回答

您的新代码在python2.6.6上运行得很好,所以您只打印最后一个缩写的问题有点神秘。不过,程序的逻辑可以做一些改进。在

首先,您应该测试用户是否想退出主循环中的。但你有一个圈外:

user_choice = raw_input() ###Determines if user quits program

在循环内部:

^{pr2}$

但是,由于您只在循环之外设置user_choice,所以测试将始终给出相同的结果,所以要么当您第一次进入while循环时立即break,不处理tweet,要么您将陷入一个无限循环中,您必须按Ctrl-C来逃离。在

主处理循环可以找到错误匹配:它将打印嵌入较长单词中的键,这可能不是您想要的。例如,如果user_tweet包含“按摩浴缸”,那么它将与“cuz”匹配。在

而且,主处理循环效率低下。在

for x in abb_dict:
    if x in user_tweet:

迭代每个tweet的整个abb_dict,然后if in测试必须线性扫描tweet,从abb_dict查找当前键的匹配项。现在,if x in user_tweet相当快,因为它以C速度运行,这意味着它比以Python速度扫描要快,但仍然效率低下。在

此外,您的代码按照缩写在字典中的存储顺序打印缩写,这可能与在字典定义中列出它们的顺序相同(由于Python字典的工作方式)。在

一个更好的策略是将tweet分成一个单词列表,然后测试每个单词是否在abb_dict中。这样,您只需线性扫描tweet两次,一次将其拆分为一个列表,另一次根据字典测试列表中的每个单词。而且测试一个键是否在字典中是非常快速和有效的,因为它不会扫描整个字典来寻找匹配项。另外,使用这个策略,你可以得到一个缩写列表,按照它们在tweet中出现的顺序排列。在

以下是代码的改进版本:

abb_dict = {
    'lol': 'laughing out loud',
    'bfn': 'bye for now',
    'cuz': 'because',
    'gtg': 'got to go',
    'brb': 'be right back',
    'nvm': 'nevermind',
    'bff': 'best friends for ever',
    'rofl': 'rolling on the floor laughing',
    'omg': 'oh my god',
}

#determines how many tweets have been decoded for exit message
t_round = 0

while True:
    user_tweet = raw_input('Type a Tweet of 160 characters or less, or q to quit: ')
    if user_tweet in "Qq":
        break

    if len(user_tweet) > 160:
        continue

    for word in user_tweet.lower().split():
        if word in abb_dict:
            print '%s: %r' % (word, abb_dict[word])

    t_round += 1

print t_round, 'tweets processed.'

测试

Type a Tweet of 160 characters or less, or q to quit: omg shut up i gtg
omg: 'oh my god'
gtg: 'got to go'
Type a Tweet of 160 characters or less, or q to quit: LOL dude brb I gtG
lol: 'laughing out loud'
brb: 'be right back'
gtg: 'got to go'
Type a Tweet of 160 characters or less, or q to quit: q
2 tweets processed.

注意,这段代码处理混合大小写,以及单词之间的各种空格,但它不处理附加了大量标点字符的缩写。另外,如果同一个缩写在tweet中出现多次,它将被打印多次。如果不需要,可以使用set来存储匹配项,并且只在set中没有匹配项时才打印它。像这样:

matches = set()
for word in user_tweet.lower().split():
    if word in abb_dict and word not in matches:
        print '%s: %r' % (word, abb_dict[word])
        matches.add(word)

测试

Type a Tweet of 160 characters or less, or q to quit: lol dude brb i GTG LOL brb gtg nvm
lol: 'laughing out loud'
brb: 'be right back'
gtg: 'got to go'
nvm: 'nevermind'
Type a Tweet of 160 characters or less, or q to quit: Q
1 tweets processed.

或者,您可以将matches = set()移到while True之前,以保持所有tweet的匹配,这样每个tweet中只会打印新的缩写。在


只要稍微修改一下代码,我们就可以用缩写词的扩展来代替缩写词:

abb_dict = {
    'lol': 'laughing out loud',
    'bfn': 'bye for now',
    'cuz': 'because',
    'gtg': 'got to go',
    'brb': 'be right back',
    'nvm': 'nevermind',
    'bff': 'best friends for ever',
    'rofl': 'rolling on the floor laughing',
    'omg': 'oh my god',
}

#determines how many tweets have been decoded for exit message
t_round = 0

while True:
    user_tweet = raw_input('Type a Tweet of 160 characters or less, or q to quit: ')
    if user_tweet in "Qq":
        break

    if len(user_tweet) > 160:
        continue

    words = []
    for word in user_tweet.split():
        word = abb_dict.get(word.lower(), word)
        words.append(word)

    print ' '.join(words)
    t_round += 1

print t_round, 'tweets processed.'    

测试

Type a Tweet of 160 characters or less, or q to quit: lol dude brb i GTG LOL brb gtg nvm
laughing out loud dude be right back i got to go laughing out loud be right back got to go nevermind
Type a Tweet of 160 characters or less, or q to quit: q
1 tweets processed.

通过使用列表理解,可以压缩中心循环(并使其更有效):

while True:
    user_tweet = raw_input('Type a Tweet of 160 characters or less, or q to quit: ')
    if user_tweet in "Qq":
        break

    if len(user_tweet) > 160:
        continue

    print ' '.join([abb_dict.get(word.lower(), word) 
        for word in user_tweet.split()])
    t_round += 1

现在看看你能不能修改这些代码来处理标点符号。:)

你的第一个解决方案是正确的。它应该输出每一个匹配,而不仅仅是最后一个。我的Python测试:

abbrev_dict = {}
abbrev_dict['omg'] = "Oh My God!"
abbrev_dict['gtg'] = "Got to go"
input = "omg shut up I gtg"

for x in abbrev_dict:
    if x in input:
        print(x + ":" + abbrev_dict[x])

# Output:
# omg:Oh My God!
# gtg:Got to go

我的猜测是abbrev_dict的键不是小写的(例如OMG而不是{}),因此与输入不匹配(强制要求是小写)。请尝试将键小写:

^{pr2}$

user_input已损坏。您忘记了调用lower中的括号。它实际上被设置为函数,而不是向下压缩的输入字符串。在

相关问题 更多 >