简介

在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅。废话不多说,现在马上开始。

使用enumerate方法替代range(len)

enumerate()中也包含了下标和值,可以很方便的进行索引和值的遍历。

  1. data = range(10000)
  2. start = time.time()
  3. data_len = len(data)
  4. for i in range(data_len):
  5. print(data[i])
  6. print(time.time() - start)
  7. start = time.time()
  8. for index, item in enumerate(data):
  9. print(index, item)
  10. print(time.time() - start)

列表生成式的使用

对于一些有规律的列表需要生成时,建议使用列表生成式进行生成,方便快捷,对于一些属性稍微复杂点的可以使用map进行批量操作。例如生成[1,4,9,16]

  1. print([item * item for item in range(1, 5)])

使用sorted对复杂对象进行排序

在对一些复杂对象进行排序时候建议使用sorted进行排序,例如字典的key或者字典的value等

  1. sorted(Iterable, key=Callable)

假设有如下列表中嵌套字典,依据age进行排序

  1. data = [
  2. {"name": "Alex", "age": 18},
  3. {"name": "Band", "age": 21},
  4. {"name": "Coco", "age": 17},
  5. ]
  6. print(sorted(data, key=lambda n: n["age"]))
  1. [{'name': 'Coco', 'age': 17}, {'name': 'Alex', 'age': 18}, {'name': 'Band', 'age': 21}]

假设有如下字典,需要将字典按照value值进行排序并返回一个字典

  1. data = {"a": 19, "c": 10, "b": 20}
  2. print(dict(sorted(data.items(), key=lambda data: data[1])))
  1. {'c': 10, 'a': 19, 'b': 20}

使用set存放唯一值\去重

set集合是无序的,值唯一,可以进行交、并、差等运算操作,除此之外,一般去重也可以使用set进行去重。

  1. data = set({1, 2, 3, 1})
  2. print(data)

使用生成器节省内存消耗

一般我们称一个函数或者方法中使用了yield方法进行返回的,则成此方法或者函数为生成器,除了这种方法之外,可以使用类似于列表生成式的方式进行操作,只需要将列表生成式的[]换成()即可,示例如下:

  1. l_data = [i for i in range(100)]
  2. print(l_data)
  3. print(sys.getsizeof(l_data))
  4. g_data = (i for i in range(100))
  5. print(g_data)
  6. print(sys.getsizeof(g_data))
  1. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
  2. 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
  3. 920
  4. <generator object <genexpr> at 0x0000028E1A626570>
  5. 104

使用sys模块的getsizeof可以获取变量的内存占用。

generator就是生成器,它不会一次性加载全部数据到内存中,只会再for循环调用或者next()\send()方法时进行懒加载方式的输出,极大的减少了内存消耗,尤其是对于数据量较大的情况。

对于字典中值的获取时建议使用get(key, default)并设置默认值

在对于字典的value值的获取中,目前有两种方式,一种是使用索引进行获取,另一种则使用get方法去获取,如下:

  1. data = {"a": 19, "c": 10, "b": 20}
  2. print(data["a"])
  3. print(data.get("a", None))
  4. print(data.get("v", None))
  5. print(data["v"])
  1. 19
  2. 19
  3. None
  4. Traceback (most recent call last):
  5. File "c:\Users\ts\Desktop\2022.7\2022.7.20\test.py", line 76, in <module>
  6. print(data["v"])
  7. KeyError: 'v'

由上述可以看出,在使用索引进行对字典value值的获取时,key存在还好,不存在则会直接报错,而采用get并设置默认值的,则会返回默认值,不会抛出异常。

统计序列中各元素个数时建议使用collection中的Counter

  1. from collections import Counter
  2. s_data = "asdfqwrewasfasdvfare"
  3. print(s_data.count("a"))
  4. print(Counter(s_data))
  5. l_data = [1, 3, 2, "a", "b", 1, "c", "a", "c"]
  6. print(l_data.count("a"))
  7. print(Counter(l_data))
  1. 4
  2. Counter({'a': 4, 's': 3, 'f': 3, 'd': 2, 'w': 2, 'r': 2, 'e': 2, 'q': 1, 'v': 1})
  3. 2
  4. Counter({1: 2, 'a': 2, 'c': 2, 3: 1, 2: 1, 'b': 1})

由上述可以看见,大部分序列都有一个count方法来获取单个元素的个数,但Counter会统计所有的个数,类似于对于每个元素进行了遍历。

格式化字符串值使用f{string}(适用于Python 3.6+)

  1. print("key:{}".format("aaa"))
  2. key = "aaa"
  3. print(f"key:{key}")
  4. print("key:%s" % (key))
  1. key:aaa
  2. key:aaa
  3. key:aaa

不过在实际使用中会发现,在部分常见下f会引起异常,可使用%s替代。

拼接字符串使用join

适用于多个元素存放在某一个序列中,纯字符串建议使用如下方法。

  1. a = "hello"
  2. b = "world"
  3. c = "!"
  4. print(a + b + c)
  5. print("{} {} {}".format(a, b, c))
  6. print(f"{a} {b} {c}")
  7. print("%s %s %s" % (a, b, c))
  8. l_data = ["hello", "world", "!"]
  9. print(" ".join(l_data))

使用双星号语法合并字典(适用于Python 3.5+)

字典之间的合并可以使用自带的update方法进行合并,注意操作的是原字典;除此之外,也可以使用双星号进行字典的合并。

  1. d1 = {"a": 1, "b": 2}
  2. d2 = {"c": 1, "d": 2}
  3. d1.update(d2)
  4. print(d1)
  5. print({**d1, **d2})

使用切片进行字符串的切割

切片一般使用[start:end:step]

  • start:开始的索引位置,包含
  • end:结束的索引位置,不包含
  • step:步长

    需要注意切片也可以从后向前,从前向后的从0开始,从后向前的从-1开始
  1. data = "asdsdfaf"
  2. # 选择所有元素
  3. print(data[::])
  4. # 选择从开始到索引为4的元素(不包含4),步长为2的元素
  5. print(data[:4:2])
  6. # 选择从索引为2的位置到索引为7的位置,步长为2的所有元素
  7. print(data[2:7:1])
  8. # 选择最后一个元素到从后向前第6个元素,步长为1的所有元素
  9. print(data[-6:-1:1])
  1. asdsdfaf
  2. ad
  3. dsdfa
  4. dsdfa

字典推导式

与列表生成式类似,但是不常使用

  1. print({item: item + 1 for item in range(10)})
  1. {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}

字典setdefault与get区别

getsetdefault都是获取字典的元素,唯一不同在于get获取不到元素后不会做任何操作,setdefault则会将不存在的元素添加至字典中。

  1. data = {"a": 1, "b": 2}
  2. print(data.get("c", 12))
  3. print(data)
  4. print(data.setdefault("c", 12))
  5. print(data)

参考

如何让python代码写的更加优雅

python代码如何写的优雅?的更多相关文章

  1. Python代码这样写更优雅(转)

    1.变量交换 大部分编程语言中交换两个变量的值时,不得不引入一个临时变量: >>> a = 1>>> b = 2>>> tmp = a>&g ...

  2. Guava - 拯救垃圾代码,写出优雅高效,效率提升N倍

    最近在看一个同学代码的时候,发现代码中大量使用了 Google 开源的 Guava 核心库中的内容,让代码简单清晰了不少,故学习分享出 Guava 中我认为最实用的功能. Guava 项目是 Goog ...

  3. 代码这样写更优雅(Python版)

    要写出 Pythonic(优雅的.地道的.整洁的)代码,还要平时多观察那些大牛代码,Github 上有很多非常优秀的源代码值得阅读,比如:requests.flask.tornado,笔者列举一些常见 ...

  4. 代码这样写更优雅(Python 版)(转载)

    转载:https://mp.weixin.qq.com/s?timestamp=1498528588&src=3&ver=1&signature=DfFeOFPXy44ObCM ...

  5. python代码这样写会更优雅

    1.链式比较操作 age = 18 if age > 18 and age < 60: print("young man") pythonic if 18 < a ...

  6. 代码这样写更优雅,15篇 Python 技术热文

    http://mp.weixin.qq.com/s?__biz=MzA4MjEyNTA5Mw==&mid=2652565527&idx=1&sn=840c1ce854afc29 ...

  7. 一行python代码能写出啥?

    1.一行代码启动一个Web服务 python -m SimpleHTTPServer 8080  # python2 python3 -m http.server 8080  # python3 2. ...

  8. 小游戏:200行python代码手写2048

    #-*- coding: utf-8 -*- import curses from random import randrange, choice from collections import de ...

  9. 【MaixPy3文档】写好 Python 代码!

    本文是给有一点 Python 基础但还想进一步深入的同学,有经验的开发者建议跳过. 前言 上文讲述了如何认识开源项目和一些编程方法的介绍,这节主要来说说 Python 代码怎么写的一些演化过程和可以如 ...

随机推荐

  1. Jmeter接口测试流程详解(中科软测认证中心)

    1.jmeter简介 Jmeter是由Apache公司开发的java开源项目,所以想要使用它必须基于java环境才可以: Jmeter采用多线程,允许通过多个线程并发取样或通过独立的线程对不同的功能同 ...

  2. DevOps之敏捷开发

    初步了解一下敏捷开发及其流程 1 为什么要敏捷开发? 敏捷开发描述了一套软件开发的价值和原则,在这些开发中,需求和解决方案皆通过自组织跨功能团队达成. 1.1 背景与动机 当需求的不明确性和工程实现的 ...

  3. JavaScript数组操作常用方法

    @ 目录 数组基础遍历方法. for for of for in 数组的基础操作方法. push:尾部追加元素 pop:尾部移出元素 unshift:头部追加元素 shift:头部移出元素 splic ...

  4. 协议层安全相关《http请求走私与CTF利用》

    0x00 前言 最近刷题的时候多次遇到HTTP请求走私相关的题目,但之前都没怎么接触到相关的知识点,只是在GKCTF2021--hackme中使用到了 CVE-2019-20372(Nginx< ...

  5. babel使用

    Babel转码器 Babel定义 Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在老版本的浏览器执行 Babel安装 仅需要在项目文件下安装 npm ins ...

  6. 面试突击51:为什么单例一定要加 volatile?

    单例模式的实现方法有很多种,如饿汉模式.懒汉模式.静态内部类和枚举等,当面试官问到"为什么单例模式一定要加 volatile?"时,那么他指的是为什么懒汉模式中的私有变量要加 vo ...

  7. 一些基本的jar包

    jackson与前端传送数据 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti ...

  8. seafile私有网盘搭建

    各种公有网盘确实很方便,但总有些特殊情况不是? 闲来无聊准备自己搭建一个私有网盘,也让自己的闲置的服务器好好利用一下 搜索一番,找到了专业户seafile 一顿操作,踩了无数大坑,特此总结一下 1.c ...

  9. C++ 智能指针浅析

    C++ 智能指针浅析 为了解决 C++ 中内存管理这个老大难问题,C++ 11 中提供了三种可用的智能指针.(早期标准库中还存在一种 auto_ptr,但由于设计上的缺陷,已经被 unique_ptr ...

  10. kruskal 及其应用

    kruskal 最小生成树 kruskal 是一种常见且好理解的最小生成树(MST)算法. 前置知识 并查集和路径压缩 生成树 在有 n 的顶点的无向图中,取其中 n-1 条边相连,所得到的树即为生成 ...