文本中的第n个单词

6
如何在文本中找到第n个单词。
示例:
my_txt("hello to you all" , 3)

all

我不想使用任何内置函数......这不是一项作业 :D


7
如果这不是作业,那么为什么不想使用内置函数? - moinudin
6
在Python中,任何事情都应该只有一种正确的方法。在这种情况下,就是使用str.split()函数。 - Rafe Kettler
5
不使用内置函数解决问题是愚蠢的。如果这不是作业,你甚至没有其他人可以责怪。如果你只是想练习重新实现内置函数,你应该首先找出你想要做哪个函数。 - Jochen Ritzel
4
顺便说一下,如果你传入的参数是“3”,这个函数应该返回“all”,而不是“you”。 - Steve V.
5
在那种情况下,我建议进行装配。 - Steve V.
显示剩余8条评论
5个回答

18

显而易见的方法是:

"hello to you all".split()[3]

80年代的做法是——也就是说,你必须遍历文本,并记录你发现过的状态——可能会有更好的方法,但这就是思路。不管哪种方法,都需要使用很多“内置”函数。我只是避免像上面那样直截了当地处理文本。

def my_txt(text, target):
    count = 0
    last_was_space = False
    start = end = 0
    for index, letter in enumerate(text):
        if letter.isspace():
            if not last_was_space:
                 end = index
            last_was_space = True
        elif last_was_space:
            last_was_space = False
            count += 1
            if count > target:
                return text[start:end]
            elif count == target:
                start = index
    if count == target:
        return text[start:].strip()
    raise ValueError("Word not found")

1
枚举、isspace、strip都是内置函数。:) 看看这变得多么愚蠢? - moinudin
看上面。但是加1让我感到头疼!(顺便说一句,你见过如何在COBOL中提取一个数字的二进制字符串表示吗? :-) - user166390
1
抱歉,代码审查发现它有一个错误。my_txt(' foo', 0) 会产生一个长度为零的字符串。my_text(' foo', 1) 会产生 'foo'。看起来 last_was_space 应该被初始化为 True - John Machin
2
@pst:如果这让你感到头疼,最好不要阅读 str.split 的真正 C 实现 :-) - John Machin

2

既然所有的东西在某种意义上都是内置函数,那我就忽略你不想使用内置函数的声明。

def my_txt(text, n):
    return text.split()[n]

这种方法的主要缺点是会包含标点符号。我将其留作练习,让您想办法去掉它。 :)

2

好的,你需要一个“拆分单词”的功能。下面是代码。该代码假设单词由空格分隔。

没有内置函数,也没有导入任何内容,不使用内置类型的方法,甚至没有像 += 这样的娘娘腔东西。并且已经测试过了。

C:\junk>\python15\python
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> def mysplit(s):
...     words = []
...     inword = 0
...     for c in s:
...         if c in " \r\n\t": # whitespace
...             inword = 0
...         elif not inword:
...             words = words + [c]
...             inword = 1
...         else:
...             words[-1] = words[-1] + c
...     return words
...
>>> mysplit('')
[]
>>> mysplit('x')
['x']
>>> mysplit('foo')
['foo']
>>> mysplit('  foo')
['foo']
>>> mysplit('  foo    ')
['foo']
>>> mysplit('\nfoo\tbar\rzot ugh\n\n   ')
['foo', 'bar', 'zot', 'ugh']
>>>

1
首先,让我说一下,我完全同意评论和其他答案,不使用内置函数是愚蠢的。话虽如此,我发现尝试使用尽可能少的内置函数调用来编写此代码是一个有趣的挑战,所以我还是会发布我想出来的内容。
def my_txt(txt, n, i=0):
    if n == 1:
        r = ""
        s = 0
        for c in txt:
            if s >= i:
                if c == " ":
                    return r
                r += c
            s += 1
    while txt[i] != " ":
        i += 1
    return my_txt(txt, n - 1, i + 1)

my_txt("hello to you all", 3) # returns 'you'

我自己设定的规则:不使用切片、列表推导、生成器或内置函数调用。

当尝试获取最后一个单词(除非有尾随空格)或任何超出单词范围的 n 时,此代码将失败得非常可怕。


谢谢,我可以用这个工作,也许在理解原理后可以使用range或len函数。 - user531225
Clark:使用递归函数调用有点作弊,不是吗? - John Machin
他说没有内置函数,我不认为递归违反了这一点。别担心,你的答案仍然更好 :) - Andrew Clark

0
显然,这并不是没有“内置函数”,但无论你多么努力,它都不会出错 :)
def my_text(string, integer=None):
  try:
    integer = int(integer)
  except ValueError:
    return 'enter a number'
  else:
    try:
      return string.split()[integer - 1]
    except IndexError:
      string = string.split()
      return f"text contains only {len(string)} word"

def inp():
  try:
    return int(input('Which word you need? ex: 1,2,3 etc.: '))
  except ValueError:
    return 'Enter number please'

print(my_text(input('Enter text here:  '), inp()))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接