Python技巧之变长和定长序列拆分

作者:Orion's?Blog 时间:2022-10-23 17:19:19 

Python中的任何序列(可迭代的对象)都可以通过赋值操作进行拆分,包括但不限于元组、列表、字符串、文件、迭代器、生成器等。

1.元组拆分

元组拆分是最为常见的一种拆分,示例如下:


p = (4, 5)
x, y = p
print(x, y) # 4 5

如果写成


x, y, z = p

那么就会抛出ValueError异常:not enough values to unpack (expected 3, got 2)”

如果写成


p = (4, 5, 6)
x, y = p

那么就会抛出ValueError异常: “ too many values to unpack (expected 2)”

2.字符串拆分

字符串的拆分示意如下:


s = 'Hello'
a, b, c, d, e = s
print(a) # H

3.拆分时丢弃值

如果在拆分时想丢弃某些特定的值,可以用一个用不到的变量名来作为丢弃值的名称(常选'_'做为变量名),如下所示:


s = 'Hello'
a, b, _, d, _ = s
print(a) # H

4.嵌套序列拆分

Python也提供简洁的对嵌套序列进行拆分的语法。如下所示我们对一个比较复杂的异质列表进行拆分:


data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, (year, month, day) = data
print(year) # 2000

如果你想完整地得到(2000, 12, 21)这个表示时间戳的元组,那么你就得这样写:


data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, date = data
print(date) # (2000, 12, 21)

5.从任意长度的可迭代对象中拆分

之前我们说过,如果我们想从可迭代对象中分解出N个元素,但如果这个可迭代对象长度超过N,则会抛出异常"too many values to unpack"。针对这个问题的解决方案是采用"*"表达式。
比如我们给定学生的分数,想去掉一个最高分和一个最低分,然后对剩下的学生求平均分,我们可以这样写:


def avg(data: list):
   return sum(data)/len(data)
# 去掉最高分,最低分然后做均分统计
def drop_first_last(grades):
   first, *middle, last = grades
   return avg(middle)
print(drop_first_last([1,2,3,4])) # 2.5

还有一种情况是有一些用户记录,记录由姓名+电子邮件+任意数量的电话号码组成,则我们可以这样分解用户记录:


record = ['zhy', 'zhy1056692290@qq.com', '773-556234', '774-223333']
name, email, *phone_numbers = record
print(phone_numbers) # ['773-556234', '774-223333']

事实上,如果电话号码为空也是合法的,此时phone_numbers为空列表。


record = ['zhy', 'zhy1056692290@qq.com']
name, email, *phone_numbers = record
print(phone_numbers) # []

还有一种使用情况则更为巧妙。如果我们需要遍历变长元组组成的列表,这些元组长度不一。那么此时*表达式可大大简化我们的代码。


records = [('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)]
for tag, *args in records:
   if tag == 'bar':
       print(args)
# ['hello']

在对一些复杂的字符串进行拆分时,*表达式也显得特别有用。


line = "nobody:*:-2:-2:-2:Unprivileged User:/var/empty:/usr/bin/false"
uname, *fields, home_dir, sh = line.split(':')
print(home_dir) # /var/empty

*表达式也可以和我们前面说的嵌套拆分和变量丢弃一起结合使用。


record = ['ACME', 50, 123.45, (128, 18, 2012)]
name, *_, (*_, year) = record
print(year) # 2012

最后再介绍*表达式用于递归函数的一种黑魔法,比如与递归求和结合可以这样写:


items = [1, 10, 7, 4, 5, 9]
def sum(items):
   head, *tail = items
   return head + sum(tail) if tail else head
print(sum(items)) # 36

不过,Python由于自身递归栈的限制,并不擅长递归。我们最后一个递归的例子可以做为一种学术上的尝试,但不建议在实践中使用它。

来源:https://www.cnblogs.com/orion-orion/p/15383250.html

标签:Python,变长,定长,序列,拆分
0
投稿

猜你喜欢

  • python 实现简单的计算器(gui界面)

    2022-11-14 14:35:14
  • Python3 json模块之编码解码方法讲解

    2021-07-15 17:29:15
  • python批量修改文件名的示例

    2023-11-04 13:50:39
  • 服务器XMLHTTP(Server XMLHTTP in ASP)基础

    2008-11-11 12:45:00
  • Python输出由1,2,3,4组成的互不相同且无重复的三位数

    2021-07-26 10:54:42
  • MySQL中Distinct和Group By语句的基本使用教程

    2024-01-26 09:51:53
  • SQL Server误区30日谈 第7天 一个实例多个镜像和日志传送延迟

    2024-01-16 19:01:01
  • SQL Server数据库搭建农村信息化的方案

    2009-01-23 14:16:00
  • oracle-快速删除重复的记录

    2008-01-16 19:12:00
  • Go 在 MongoDB 中常用查询与修改的操作

    2024-04-26 17:18:04
  • python魔法方法之__setattr__()

    2021-06-06 13:27:47
  • python调用接口的4种方式代码实例

    2022-01-15 17:03:30
  • Django基础CBV装饰器和中间件的应用示例

    2023-09-30 06:17:07
  • Python中寻找数据异常值的3种方法

    2023-10-18 11:21:41
  • 以用户为中心的WEB表单

    2010-08-03 12:11:00
  • python中sleep函数用法实例分析

    2023-10-19 15:33:24
  • golang设置http response响应头与填坑记录

    2024-05-21 10:22:24
  • 中国传统色彩名录

    2007-11-29 18:36:00
  • python如何更新包

    2023-12-06 10:36:59
  • Sql 批量查看字符所在的表及字段

    2024-01-15 02:53:36
  • asp之家 网络编程 m.aspxhome.com