【问题标题】:List slicing issues in python列出python中的切片问题
【发布时间】:2014-08-14 18:46:21
【问题描述】:

这段代码看起来应该可以工作。它总结了“条纹”(字母-辅音-字母等)的单词数,然后返回总和。但是,当我使用 print (striped("My name is ...") ) 对其进行测试时,它只计算 myis 并给我一个 2 而不是 3 的总和...为什么缺少 name

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"


def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = VOWELS.lower()
    consonants = CONSONANTS.lower()

    for word in text:
        word = word.lower()
        if ((word[::2] in vowels and word[1::2] in consonants)\
        or (word[::2] in consonants and word[1::2] in vowels))\
        and len(word) > 1:
            print (word)
            my_sum += 1

    return my_sum        

【问题讨论】:

  • 也不要使用sum!阴影内置
  • 好的,现在也改变了!仍然无法正常工作...而且我一直为此使用 sum,到目前为止它没有给我带来任何问题...?
  • 你应该已经修复了缩进。
  • 再次剪切和粘贴错误...已修复
  • @ejLev 哦,对不起,我只是指出,如果你有一组东西,你可以生成互补集,而不是硬编码。换句话说,如果你有一组元音,那么这组辅音只是互补集(在大写 ascii 字母的宇宙中)。所以你可以生成它,而不是硬编码它。当集合更大时,这具有更大的价值。 :)

标签: python python-3.x slice


【解决方案1】:

这是一个带有列表的解决方案。您的代码的问题是,当您使用[::2] 时,超过两个字符的单词会返回一个子字符串,而不是测试它们是否包含在vowels / constants 中的单个字符。 通过先将其转换为列表,您可以检查列表中的每一项是否包含在相应的字符集中。

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"


def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = VOWELS.lower()
    consonants = CONSONANTS.lower()

    for word in text:
        word = word.lower()

        if ((all(c in vowels for c in list(word[::2]))\
            and all(c in consonants for c in list(word[1::2])))\
        or (all(c in consonants for c in list(word[::2]))\
            and all(c in vowels for c in list(word[1::2]))))\
        and len(word) > 1:
            print (word)
            my_sum += 1

    return my_sum

print striped("My name is")

【讨论】:

  • 那里需要一个额外的括号,将and 语句与or 隔离开来
  • 谢谢你这工作完美,但我仍然不完全理解整个(all(c in vowels for c in list(word[::2])你有没有机会逐部分简要解释一下?
  • 好的,让我们从list(word[::2])开始。假设单词是 'name',[::2] 返回 'nm',它不会出现在元音中,因为测试的是整个字符串而不是单个字符。这就是为什么它首先转换为列表的原因。 for c in list(word[::2]) 意味着遍历单词的每个字符 (c)。单独检查每个字符是否包含在vowels 中。 all() 如果可迭代的所有元素都为真,则返回真,在这种情况下,c in vowels 与内联 for 循环结合使用。另请参阅docs.python.org/2/library/functions.html#all
【解决方案2】:

您应该改用set.issubset()

VOWELS = "AEIOUY"
CONSONANTS = "BCDFGHJKLMNPQRSTVWXZ"

def striped(text):

    my_sum = 0
    text = text.replace(".", " ").replace(",", " ").split()
    vowels = set(c for c in VOWELS.lower())
    consonants = set(c for c in CONSONANTS.lower())

    for word in text:
        word = word.lower()
        if ((set(word[::2]).issubset(vowels) and set(word[1::2]).issubset(consonants))\
        or (set(word[::2]).issubset(consonants) and set(word[1::2]).issubset(vowels)))\
        and len(word) > 1:
            print (word)
            my_sum += 1
    return my_sum        

striped('My name is...')

它适用于myis 的原因是它们是两个字符词,因此您要检查m 是否在常量字符串中,以及y 是否在元音字符串中,这有效。对于像name 这样更长的词,那么显然nm 不在子音串中,所以它失败了。


相反,您应该使用集合。本质上,您想查找set(['n','m']) 是否是辅音集的子集。

【讨论】:

  • set 的问题是每个字母都只有一次,因此它不适用于某些字符出现多次的单词。你可以改用list
  • 这不起作用,因为现在我只是用 striped("ballllllllllll") 尝试了它,它给了我一个 my_sum 1,而它显然应该是 0
  • 您应该在原始问题中包含一组测试值,@ejLev
  • @EspartaPalma 你这是什么意思?
  • 在您的帖子中添加要测试的值:striped("My name is...") --> 3 striped("ballllllllll") --> 0 ....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 2011-01-28
  • 2023-02-25
  • 2018-08-31
相关资源
最近更新 更多