驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
python的杂谈
/  

python的杂谈

list[obj] 转为字符串

  • 利用split_str.join(list)
  • 其中obj是字符串,那么就简单了,否则的话,必须将 obj 转为 str,python 一点都不智能,不自己去转换。
class Blog:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name
      
if __name__ == '__main__':
    bl = [Blog("a"), Blog("b")]
    ls = ["a", "b", "c"]
		# a,b,c
    print(",".join(ls)) 
    # a-b-c
    print("-".join(ls))
    # TypeError: sequence item 0: expected str instance, Blog found
    print("-".join(bl))
    # `[-<-_-_-m-a-i-n-_-_-.-B-l-o-g- -o-b-j-e-c-t- -a-t- -0-x-1-0-5-8-9-5-e-9-0->-,- -<-_-_-m-a-i-n-_-_-.-B-l-o-g- -o-b-j-e-c-t- -a-t- -0-x-1-0-5-8-9-5-d-d-0->-]`
    print("-".join(str(bl)))

比如上述代码中:

  • ",".join(ls)"-".join(ls)都是没有问题,能够正常输出的。

  • "-".join(bl)这句代码执行的时候

    • 报错了TypeError: sequence item 0: expected str instance, Blog found。提示:期望的是 str,单却找到的是 Blog
    • 所以更换为"-".join(str(bl))。但是结果:[-<-_-_-m-a-i-n-_-_-.-B-l-o-g- -o-b-j-e-c-t- -a-t- -0-x-1-0-5-8-9-5-e-9-0->-,- -<-_-_-m-a-i-n-_-_-.-B-l-o-g- -o-b-j-e-c-t- -a-t- -0-x-1-0-5-8-9-5-d-d-0->-]。很明显和预期不符

分析和结论

  • 上面我很好奇啊,我已经重写了Blog#str了啊,为什么还输出那个?

  • 我们来看看方法的签名str.join(iterable)。join 的是一个可遍历的对象,我传入的是一个 str(blog)。我们看下面的代码:

  •     bl = [Blog("a"), Blog("b")]
        print(str(bl))
    		# [<__main__.Blog object at 0x10361bd90>, <__main__.Blog object at 0x103621290>]
    
  • str(bl)是一堆字符串,类似 Java 代码中你传入的是List<Person> lp 中的lp

  • 正常的做法应该是:

  • if __name__ == '__main__':
        bl = [Blog("a"), Blog("b")]
        bstr = [str(b) for b in bl]
        result = "-".join(bstr)
        print(result)
        # a-b
    

经过测试和思考,

这里 不管是 java 还是 C#都比 python 更智能了。

不过不管哪种语言,都有各自的优点和不足。

zip 和 dic 函数的互动

zip函数是将 2 个可以遍历的对象,组成tuple

L1 = [1, 2, 3]
S2 = {"A", "B", "C"}
L3 = ["10", "9", "8", "7"]

if __name__ == '__main__':

    t1 = zip(L1, S2)
    t2 = zip(L1, L3)
    t3 = zip(L1, S2, L3)
    for s1, s2 in t1:
        print(str(s1) + "-" + s2)

大家不明白的,自己尝试执行下就知道了。

其中 t1 的结果可以表示为

(1,"A"),(2,"B"),(3,"C")

这种表示很像字典啊,很显然python也支持我们这么转。

dict(zip(L1,S2))

slice 切片

我认为python这个功能比 Java 更好用。

语法:[start:end:step]

其中每个参数都可以不写,这样他们会有默认值代替

  • start 的默认值为 0
  • end 的默认值为 长度
  • step 的默认值为 1

直接看代码

L3 = ["10", "9", "8", "7"]

if __name__ == '__main__':
    print(L3[2::]) # ['8', '7']
    print(L3[:2:]) # ['10', '9']
    print(L3[::2])  # ['10', '8']
    print(L3[2:3:]) # ['8']
    print(L3[:2:1]) # ['10', '9']
    print(L3[1:2:1]) #['9']

这个语法太简洁了吧!怪不得:人生苦短,我用 python

结语

这篇文章虽然短,但是花了我 1 个小时还多,主要是 2 个原因:

  • 查看之前写的 python 代码的时候,一直在在反思自己在 python 踩了那些坑,这些坑下 java或者 c#或者 kotlin 下是否也会犯。
  • 思考 python 和 java 的不同,此时又有点感觉了,python 更抽象,更简洁,不够语义化。比如 java用的 stream+filter,python 一个 for表达式搞定。比如 python 的切片,简洁确实简洁,但是不够语义化。
不积跬步,无以至千里。不积小流,无以成江海。