Python基础语法练习2-The Hidden Word

文章目录

  • 前言
  • 一、题目介绍
  • 二、代码展示
    • 1. 本人代码
    • 2. 优秀代码
      • 2.1 zip()
      • 2.2 zip_longest()
  • 三、总结


前言

在checkio上又看到这么一个题,题目看似简单,而且难度设定是simple+,我以为随便就能写出来,没想到for if了一堆…[#滑稽]


一、题目介绍

"""已知一段用回车分隔的长字符串rhyme(类似一首诗的结构)和一个短字符串word,
要求去掉长字符串中的空格之后,形成一个类似字符矩阵的形式,然后在里面找到那个短字符串(忽略大小写),并输出坐标。

坐标的形式为(开始行,开始列,结束行,结束列)
"""

这里用一个例子表示更直观一些:
Python基础语法练习2-The Hidden Word_第1张图片

二、代码展示

1. 本人代码

这里我的想法是逐行遍历,在每一行中再逐个字母遍历,如果找到word的第一个字母,就检查此字母的横向或纵向,如果和word全部匹配就返回,否则只要有一个不同直接break,继续遍历。代码如下:

def checkio(text, word):
	# rhyme转换成列表
    ls = text.replace(' ','').lower().split('\n')
    # 存储结果
    result = []
    n = len(word)
    for i in range(len(ls)):
        for j in range(len(ls[i])):
        	if ls[i][j] == word[0]:
            	# 如果找到的字母在一行末尾,直接看列就可以
                if j == len(ls[i]) - 1:
                    for k in range(n):
                        if ls[i+k][j] == word[k]:
                            continue
                    result.extend([i+1, j+1, i+n, j+1])
                    return result
                # 否则需要行和列都看
				for x in range(n):
					# 在同行寻找word
                    if ls[i][j+x] != word[0+x]:
                    	# 行找不到找列
                        for y in range(n):
                            if ls[i+y][j] != word[0+y]:
                            	# 列也找不到,直接退出此次循环
                                break
                        else:
                            result.extend([i+1, j+1, i+n, j+1])
                            return result
                        break
                else:
                    result.extend([i+1, j+1, i+1, j+n])
                    return result
            j += 1
        i += 1

2. 优秀代码

一个simple+的题目被我写成这样,难受啊。于是看了别的小伙伴的作业,确实有一些很厉害的,比如这个:

from itertools import zip_longest


def checkio(text, word):
    horizontal = text.lower().replace(' ', '').splitlines()
    for i, row in enumerate(horizontal, 1):
        index = row.find(word)
        if index >= 0:
            return [i, index+1, i, index+len(word)]

    vertical = [''.join(line) for line in zip_longest(*horizontal, fillvalue='-')]
    for i, col in enumerate(vertical, 1):
        index = col.find(word)
        if index >= 0:
            return [index+1, i, index+len(word), i]

这段代码真的厉害,我是逐个字母对比,而他是直接find word。值得注意的是,这段代码引用了一个zip_longest()函数,这是个什么函数呢?

2.1 zip()

我们都知道zip()函数,zip([seq1, …])接受一系列可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。若传入参数的长度不等,则返回列表的长度和参数中长度最短的对象相同。

>>> ls1 = ['a', 'b', 'c']
>>> ls2 = [1, 2, 3]
>>> print(zip(ls1, ls2))
<zip object at 0x0530BC88>
>>> print(list(zip(ls1, ls2)))
[('a', 1), ('b', 2), ('c', 3)]
>>> ls3 = ['A', 'B']
>>> print(list(zip(ls1, ls3)))
[('a', 'A'), ('b', 'B')]

2.2 zip_longest()

这个函数需要导入itertools模块,和zip()函数功能类似,区别在于zip()函数在两个参数长度不等时,返回列表的长度与较短的对象保持一致;而zip_longest则与较长的对象保持一致。对于不足的部分默认用None补齐,但是可以使用fillvalue参数来指定。

>>> from itertools import zip_longest
>>> ls1 = ['a', 'b', 'c', 'd']
>>> ls2 = [1,2,3]
>>> print(list(zip_longest(ls1, ls2)))
[('a', 1), ('b', 2), ('c', 3), ('d', None)]
>>> print(list(zip_longest(ls1, ls2, fillvalue='马拉卡')))
[('a', 1), ('b', 2), ('c', 3), ('d', '马拉卡')]

三、总结

这道题如果用常规方法确实比较麻烦,看着简单,却要逐个遍历确定。如果直接查找整个word会快很多,但用这种思路,水平方向还好,垂直方向很难连成一个词,这就要用到zip_longest()函数。通过这次的学习,了解了一个新的第三方函数,以后应该还会用到。

你可能感兴趣的:(Python基础语法练习,python,字符串)