python 50个实用编程技巧(一)

  • Post author:
  • Post category:python




1. 如何在列表,字典、集合中根据条件筛选数据?

  • 实际案例

    过滤掉列表[3, 9, -1, 10, 20, -2]中的负数

    筛出字典{“LiLei”:79, “Jim”:88, “Lucy”:92}中值高于90的项

    筛出集合{77, 89, 32, 20}中能被3整除的元素
  • 解决方案:

    • 列表,字典,集合解析(

      推荐

      ):

      [x for x in data in x >= 0]
      {k:v for k, v in d.items() if v > 90}
      {x for x in s if x%3 ==0}
      
    • filter函数

      filter(lambda x:x>=0, data)
      filter(lambda item: item[1] >= 90, d.items())
      filter(lambda x: x%3 == 0, s)
      



2. 如何为元组中的每个元素命名,提高程序可读性?

  • 实际案例

    学生信息系统中数据为固定格式:(名字,年龄, 性别, 邮箱)

    (“Jim”, 16, “male”, “jim8721@gmail.com”)

    (“LiLei”, 16, “male”, “lilei@gmail.com”)

    访问时,使用索引(index)访问,大量索引降低程序可读性

    def xxx_func(student):
        if student[1] < 18:        # 使用index, 程序可读性差
            pass
    
        if student[2] == 'male':   # 使用index, 程序可读性差
            pass
    
    
    student = ('Jim', 16, 'male', 'jim8721@gmail.com')
    xxx_func(student)
    
  • 解决方案

    方案1: 定义一系列数值常量或枚举类型

    数值常量

    # 使用一系列常量值 
    NAME = 0
    AGE = 1
    SEX = 2
    EMAIL = 3
    # 或者
    NAME, AGE, SEX, EMAIL = range(4)
    
    def xxx_func(student):
        if student[AGE] < 18:
            pass
    
        if student[SEX] == 'male':
            pass
    
    student = ('Jim', 16, 'male', 'jim8721@gmail.com')
    xxx_func(student)
    

    枚举方法

    from enum import IntEnum
    class StudentEnum(IntEnum):
        NAME = 0
        AGE = 1
        SEX = 2
        EMAIL = 3
    
    
    def xxx_func(student):
        if student[StudentEnum.AGE] < 18:
            pass
    
        if student[StudentEnum.SEX] == 'male':
            pass
    
    
    student = ('Jim', 16, 'male', 'jim8721@gmail.com')
    xxx_func(student)
    

    方案2:使用标准库中 collections.namedtuple替代内置tuple (推荐)

    from collections import namedtuple
    
    Student = namedtuple("Student", ["name", "age", "sex", "email"])
    
    def xxx_func(student):
        if student.age < 18:        # 使用index, 程序可读性差
            pass
    
        if student.sex == 'male':   # 使用index, 程序可读性差
            pass
    
    
    student = Student('Jim', 16, 'male', 'jim8721@gmail.com')
    xxx_func(student)
    



3. 如何根据字典中值的大小,对字典中的项排序?

  • 实际案例

    某班英语成绩以字典形式存储形式如下,根据成绩高低进行排序:

    {
        "LiLei": 79, 
        "Jim": 88,
        "Lucy": 92
    }
    
  • 解决方案

    使用内置函数sorted排序

    d = {'h': 98, 'm': 88}
    sorted(d.items(), key=lambda item: item[1], reverse=True)
    



4. 如何统计序列中元素的频度

  • 实际案例

    某随机序列[2,3,4,6,7,1,3,3,8,9]中,找出出现次数最高的3个元素,它们出现次数是多少?

  • 解决方案

    方案一:使用标准库collections中的Counter对象

    from collections import Counter
    data = [2,3,4,6,7,1,3,3,8,9]
    
    c = Counter(data)
    
    b = c.most_common(3)  #
    print(b)  # 输出[(3, 3), (2, 1), (4, 1)]
    

    如果是取data是前三个最大值,可以不用完全排序,使用heapq

    import heapq
    d = heapq.nlargest(3, data)
    print(d) # [9, 8, 7]
    

    方案二:先用字典记录各值出现的次数,再按次数进行排序取前三

    data = [2,3,4,6,7,1,3,3,8,9]
    
    d = dict.fromkeys(data, 0)
    for x in data:
        d[x] += 1
    e = sorted(d.items(), key=lambda item: item[1], reverse=True)[:3]
    print(e)  # [(3, 3), (2, 1), (4, 1)]
    



5. 如何快速找到多个字典中的公共键?

  • 实际案例

    西班牙足球甲级联赛,每轮球员进球统计如下,统计出前N轮,每场比赛都有进球的球员

    [{"苏亚雷斯": 1, "梅西": 2, "本泽马": 1},
         {"苏亚雷斯": 2, "C罗": 2, "贝尔": 1},
         {"苏亚雷斯": 1, "C罗": 2, "梅西": 1},
         ...
    ]
    
  • 解决方案

    利用集合(set)的交集操作

  1. 使用的keys()方法,得到一个字典keys的集合
  2. 使用map函数,得到每个字典keys的集合
  3. 使用reduce函数,取所有字典的keys集合的交集

    from functools import reduce
    
    data = [{"苏亚雷斯": 1, "梅西": 2, "本泽马": 1},
         {"苏亚雷斯": 2, "C罗": 2, "贝尔": 1},
         {"苏亚雷斯": 1, "C罗": 2, "梅西": 1}
    ]
    
    c = reduce(lambda a, b: a & b, map(dict.keys, data))
    print(list(c))  # ['苏亚雷斯']
    



6. 如何让字典保持有序?

  • 有序定义:字典存储的数据和输入的顺序一致,如

    在这里插入图片描述

  • 解决方案

    使用标准库collections中的OrderdDict

    from collections import OrderedDict
    
    d = OrderedDict()
    d['c'] = 1
    d['b'] = 2
    d['a'] = 3
    print(d)  # 输出OrderedDict([('c', 1), ('b', 2), ('a', 3)])
    

注:python3.6后,系统默认的字典是有序,3.6之前是无序的



7. 如何实现用户的历史记录功能(最多n条)?

  • 实际案例

    制作一个简单的猜数字的小游戏,如何添加历史记录功能,显示用户最近猜过的数字?

  • 解决方案:

    • 使用标准库collections中的deque, 它是一个双端循环队列
    • 使用pickle模块将历史记录存储到硬盘,以便下次启动使用

    代码如下:

    from collections import deque
    from random import randint
    import pickle
    import os
    
    
    # target为目标数, g为猜的数
    def guess(target, g):
        if target == g:
            print("猜对了,这个数字是%d" % g)
            return True
        if target < g:
            print("猜大了, 比%d小" % g)
        elif target > g:
            print("猜小了, 比%d大" % g)
        return False
    
    
    def main():
        target = randint(1, 100)
        i = 1
    
        his_filename = "save.pkl"  # 历史数据文件名
        if os.path.exists(his_filename):
            hq = pickle.load(open(his_filename, 'rb'))
        else:
            hq = deque([], 5)  # 记录5个历史数据
    
        while True:
            line = input("[%d] 请输入一个数字:" % i)
            if line.isdigit():
                g = int(line)
                hq.append(g)  # 将数据存储
                i += 1
                if guess(target, g):
                    break
            elif line == 'quit':
                pickle.dump(hq, open(his_filename, 'wb'))
                break
            elif line == "h?":
                print(list(hq))
    
    
    if __name__ == "__main__":
        main()
    

待续。。。



版权声明:本文为qq_34809033原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。