简体   繁体   English

如何判断函数在Python中返回的值?

[英]How can I tell what value my function is returning in Python?

I'm trying to debug this program I wrote. 我正在尝试调试我编写的程序。 How can I tell if, for a given word , hand , and word_list , it returns True or False? 如何判断给定的wordhandword_list是否返回True或False? I tried initializing a variable failure and then modifying it and printing it's value. 我尝试初始化变量失败 ,然后修改它并打印它的值。 It isn't printing, so I don't know if it is behaving like it's supposed to. 它不是在打印,所以我不知道它的行为是否如预期的那样。 Any help is appreciated. 任何帮助表示赞赏。

I have a function load_words() that returns a list of words. 我有一个函数load_words()返回一个单词列表。 I know word is in word_list (I checked), so just trying to see if word is composed entirely of letters from the keys in the dictionary hand , which in this case it isn't, so it should return False. 我知道这个词是在WORD_LIST(我查了),所以只是想看看完全是从字典中的 ,在这种情况下,它是不是按键的字母组成的,所以它应该返回False。

Also, what is the difference between .keys() and .iterrkeys(), and is there a better way of looping through hand , perhaps with letter, value in hand.iteritems() ? 此外,.keys()和.iterrkeys()之间有什么区别,还有没有更好的方法来遍历 (可能带有hand.iteritems()的字母)值

word = 'axel'

hand2 = {'b':1, 'x':2, 'l':3, 'e':1}

def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.

    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
    failure = False
    if word in word_list:
        print hand
        print [list(i) for i in word.split('\n')][0]
        for letter in [list(i) for i in word.split('\n')][0]:
            print letter
            if letter in hand.keys():
                print letter
                return True
                failure = True
                print failure
            else:
                return False
                failure = False
                print failure
    else:
        return False
        failure = False
    print failure

is_valid_word(word,hand2,load_words())

UPDATE I wish to use this function in my function, but it gives a key error, even though it works fine on its own. UPDATE我希望在我的函数中使用此函数,但是它会给出一个关键错误,即使它本身可以正常工作也是如此。

def update_hand(hand, word):
    """
    Assumes that 'hand' has all the letters in word.
    In other words, this assumes that however many times
    a letter appears in 'word', 'hand' has at least as
    many of that letter in it. 

    Updates the hand: uses up the letters in the given word
    and returns the new hand, without those letters in it.

    Has no side effects: does not modify hand.

    word: string
    hand: dictionary (string -> int)    
    returns: dictionary (string -> int)
    """
    for letter in [list(i) for i in word.split('\n')][0]:
        if letter in hand.keys():
            hand[letter] = hand[letter]-1
        if hand[letter] <= 0:
            del hand[letter]
    display_hand(hand)
    return hand

The reason why it is not printing out is because you are returning the function before it print s. 它不打印出来的原因是因为您要在print s之前返回该函数。 This means that the program stops before it reaches the print statement. 这意味着程序在到达print语句之前就停止了。 For example: 例如:

def foo(x):
    return x
    print x

foo("asdf")

Will return nothing while: 在以下情况下将不返回任何内容:

def foo(x):
    print x
    return x

foo("asdf")

Will print : print

asdf

So, all your statements before return . 因此,您在return之前的所有语句。 If not, it will not execute. 如果没有,它将不会执行。

For your second clarification, this post already has your answer https://stackoverflow.com/a/3617008 : 为了进一步澄清,这篇文章已经有了您的答案https://stackoverflow.com/a/3617008

In Python 2, iter(d.keys()) and d.iterkeys() are not quite equivalent, although they will behave the same. 在Python 2中, iter(d.keys())d.iterkeys()并不完全等效,尽管它们的行为相同。 In the first, keys() will return a copy of the dictionary's list of keys and iter will then return an iterator object over this list, with the second a copy of the full list of keys is never built. 在第一个中, keys()将返回字典的键列表的副本,然后iter将在此列表上返回一个迭代器对象,第二个,则永远不会构建完整的键列表的副本。

Note that Python 3 does not have .iterkeys() too. 请注意,Python 3也没有.iterkeys() Python 3 uses the previous .iterkeys() as the new .keys() . Python 3使用先前的.iterkeys()作为新的.keys()

Lastly , I will review what is generally wrong with your code and what you want to achieve in descending order of severity. 最后 ,我将回顾您的代码普遍存在的问题以及您要实现的严重性从高到低的顺序。

  1. Your code only checks one letter 您的代码仅检查一个字母
  2. [list(i) for i in word.split('\\n')][0] is not how you get all the letters from a word. [list(i) for i in word.split('\\n')][0]并不是从单词中获取所有字母的方式。
  3. You should make short code return first so that you would not have big indent blocks. 您应该首先返回短代码,这样就不会有大的缩进块。

Your code only checks one letter 您的代码仅检查一个字母

In your for loop, you return True immediately after the first word is checked. 在for循环中,检查第一个单词后立即return True You should return True after the loop is completed instead. 您应在循环完成后return True

for letter in word:
    if letter not in hand.keys():
        return False
return True

List comprehension 清单理解

Your list comprehension is not needed (I'll tell you why later) and need not be so complex just to get the letters from a word. 您不需要列表理解(稍后会告诉您原因),并且不必太复杂,仅从单词中获取字母即可。 Eg 例如

[list(i) for i in word.split('\n')][0]

Actually only does this: 实际上只这样做:

list(word)

In fact, you should just iterate through the word directly (as I did above), it will return the letters one by one: 实际上,您应该直接对单词进行直接迭代(就像我之前所做的那样),它将一一返回字母:

for letter in word:
    # code...

Make short code return first 先让短代码返回

Usually I dislike big chunks of highly indented code. 通常我不喜欢大块高度缩进的代码。 What you can do is make the short code return first. 您可以做的是先让短代码返回。 For example: 例如:

if word in word_list:
    for letter in word:
        if letter in hand.keys():
            return True
        else:
            return False
else:
    return False

Can be simply be written as: 可以简单地写成:

if word not in word_list:
    return False

for letter in word:
    if letter in hand.keys():
        return True
    else:
        return False

However, this is just my opinion. 但是,这只是我的意见。 Some others may prefer the else statement so that they know when the code is executed. 其他一些人可能更喜欢else语句,以便他们知道何时执行代码。

Your final code would look like: 您的最终代码如下所示:

def is_valid_word(word, hand, word_list):
    if word not in word_list:
        return False

    for letter in word:
        if letter not in hand.keys():
            return False
    return True

Clean right? 干净吧? However, I assume that you are making something like a scrabble game, so you would count if the words in your hand can for the word you chose. 但是,我假设您正在制作类似拼字游戏的游戏,因此您可以算出您hand的单词是否能代表您选择的单词。 What you can add is something to count if the number of letters in the word is less than or equal to the number of letters in your hand: 如果单词中的字母数小于或等于您手中的字母数,您可以添加一些要计数的东西:

def is_valid_word(word, hand, word_list):
    if word not in word_list:
        return False
    # This makes the word into a "unique list"
    letters = set(word)
    for letter in letters:
        if hand[letter] < word.count(letter):
            return False

    return True

EDIT There was a problem with the code. 编辑代码有问题。 It does not check if the letter is in hand in the if statement: if hand[letter] < word.count(letter): . 它不检查,如果letter是在hand的if语句: if hand[letter] < word.count(letter):

def is_valid_word(word, hand, word_list):
    if word not in word_list and word not in hand.keys():
        return False
    letters = set(word)
    for letter in letters:
        # Add this extra clause
        if letter in hand.keys() or hand[letter] < word.count(letter):
            return False

    return True

您可以直接print is_valid_word(word,hand2,load_words())结果print is_valid_word(word,hand2,load_words())

You have some indentation issues, and doing something after a return statement is futile. 您有一些缩进问题, return语句之后做一些事是徒劳的。

You don't need to use keys or iterkeys the in operator will check for you, and will work with lists, set, dicts (keys), tuples, strings, ... 您不需要使用keysiterkeysin运算符将为您检查,并且可以使用列表,集合,字典(键),元组,字符串等。

The in operator invokes __contains__ which is supported by most python collections. in运算符会调用__contains__ ,这是大多数python集合所支持的。

Also have look at https://docs.python.org/2/reference/expressions.html#membership-test-details . 也可以查看https://docs.python.org/2/reference/expressions.html#membership-test-details

He is a minimized example of what you want to do with 3 tests. 他是您要进行3个测试的最小化示例。

def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely composed
    of letters in the hand. Otherwise, returns False.  Does not mutate
    hand or word_list.

    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings

    """

    if word not in word_list:
        return False

    for letter in word:
        if letter not in hand:
            return False

    return True

print(is_valid_word('bxel',
                    {'b': 1, 'x': 2, 'l': 3, 'e': 1},
                    ['foo', 'bar', 'bxel']))
print(is_valid_word('axel',
                    {'b': 1, 'x': 2, 'l': 3, 'e': 1},
                    ['foo', 'bar', 'axel']))
print(is_valid_word('axel',
                    {'a': 1, 'x': 2, 'l': 3, 'e': 1},
                    ['foo', 'bar', 'axel']))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM