鱼C论坛

 找回密码
 立即注册
查看: 2115|回复: 9

列表推导式的作业题

[复制链接]
发表于 2023-5-4 18:57:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x



>>> list1 = ['1.Just do it!', '2.一切皆有可能!', '3.让编程改变世界!', '4.Impossible is Nothing!']
>>> list2 = ['4.阿迪达斯', '2.李宁', '3.鱼C工作室', '1.耐克']
>>> list3 = [name + ':' + slogan[2:] for slogan in list1 for name in list2 if slogan[0] == name[0]]
>>> print(list3)
['1.耐克:Just do it!', '2.李宁:一切皆有可能!', '3.鱼C工作室:让编程改变世界!', '4.阿迪达斯:Impossible is Nothing!']
>>> for each in list3:
        print(each)

      
1.耐克:Just do it!
2.李宁:一切皆有可能!
3.鱼C工作室:让编程改变世界!
4.阿迪达斯:Impossible is Nothing!


我的问题是针对 list3 = [name + ':' + slogan[2:] for slogan in list1 for name in list2 if slogan[0] == name[0]]

1.小甲鱼不是说不要使用连接符+来拼接字符串吗?

2、list3的推导式有点看不明白:书上很多内容看懂了,但一旦到了实战或作业题,好像还是一知半解,比如列表分片有点乱
(1)slogan[2:]是指list1中去除序号和点以后的内容?为什么可以这样表示?我特地测试了下面的
>>> str1 = 'laizhibin'
>>> str1[2]
'i'
>>> str1[2:]
'izhibin'

>>> str2 = ['laizhibin']
>>> str2[2]
Traceback (most recent call last):
  File "<pyshell#165>", line 1, in <module>
    str2[2]
IndexError: list index out of range
>>> str2[2:]
[]

>>> str3 = ['1.Just do it!', '2.一切皆有可能!', '3.让编程改变世界!', '4.Impossible is Nothing!']
>>> str3[2]
'3.让编程改变世界!'
>>> str3[2:] # 与slogan[2:]返回结果完全不同!!!
['3.让编程改变世界!', '4.Impossible is Nothing!']

(2)slogan[0]和name[0]分别是指list1和list2中的序号吧?为什么可以这样表示?

(3)slogan[0] == name[0]是为了在list1和list2中通过序号建立一一对应的关联关系?

3、生成结果为何会按1-4的顺序排列呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-4 19:05:24 | 显示全部楼层
1. 小甲鱼的意思可能是避免在循环中使用 "+" 或 "+=" 操作符来更新字符串,尽量采用 str.join() 方法连接字符串对象。但在这里对于一个简单的字符串拼接操作,使用加号操作符也是可以的。

2. (1) slogan[2:] 的确指的是去除了 "序号." 后剩下的字符串内容。例如 '1.just do it!' 中 slogan[2:] 等于 'just do it!' 。 这种写法相当于“对序号和‘.’进行分片”,即取 [2:] 位置以后的全部字符。

    (2) slogan[0] 和 name[0] 分别指的是每条口号(slogan)和品牌名称(name)的第一个字符。例如 '1.just do it!' 中 slogan[0] 等于 '1' ,而 name[0] 等于 '耐' 。使用 slogan[0] 和 name[0] 来作为判断条件,是为了使得每个品牌都能够绑定一条对应的口号。

    (3) 是的,正如前面所说,slogan[0] 和 name[0] 用于判断每个品牌和对应口号之间是否存在匹配。只有当 slogan[0] 等于 name[0] 时,才满足条件,从而被添加到 list3 中。

3. 因为在 list2 中定义的品牌顺序是按照题目要求手动排列的,与 list1 中的序号对应。在列表生成式中首先循环 list1 中的每条口号,然后根据 slogan[0] 和 name[0] 是否相等来判断品牌和口号之间是否有匹配,只有当两者匹配时才能将结果添加到 list3 中。由于 list2 中品牌的定义顺序是符合题目要求的,因此最终生成的 list3 中的品牌顺序也是符合要求的。换句话说,虽然在这个列表推导式中没有直接使用 list2,但是 list2 中品牌的手动指定顺序在整个匹配过程中仍有用到,并最终反映在了 list3 的排序中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-4 20:24:44 | 显示全部楼层
1. 是的,小甲鱼推荐避免使用 + 连接符拼接字符串,因为它会产生新的字符串对象,对内存和性能不友好。但在这个例子里,为了简洁和方便,我们仍然使用了 + 连接符。实际上,可以使用更高效的方式,如  ''.join()  或者使用 f-string(Python 3.6+)来实现。

2. 正确理解列表推导式:
(1) slogan[2:]  的确表示去除序号和点后的内容。在这里, slogan  是字符串,而不是列表,所以它表示的是从字符串的第3个字符(索引为2)开始,一直到字符串末尾的所有字符。
(2) slogan[0]  和  name[0]  是字符串slogan和name中的第一个字符,也就是序号。这里是通过字符串的索引访问特定位置的字符。
(3)是的, slogan[0] == name[0]  是为了在 list1 和 list2 之间通过序号建立一一对应的关联关系。

3. 结果按照 1-4 的顺序排列,是因为推导式的for循环按照列表的顺序进行。首先它遍历 list1,然后针对每个 list1 的元素,它遍历 list2。这样,当找到相应序号匹配的 name 和 slogan 时,它会按照 list1 的顺序来创建 list3。由于 list1 的元素是按照 1-4 的顺序排列的,所以 list3 中的元素也会按照相应的顺序排列。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-4 20:51:15 | 显示全部楼层
sfqxx 发表于 2023-5-4 19:05
1. 小甲鱼的意思可能是避免在循环中使用 "+" 或 "+=" 操作符来更新字符串,尽量采用 str.join() 方法连接字 ...


(2) slogan[0] 和 name[0] 分别指的是每条口号(slogan)和品牌名称(name)的第一个字符。例如 '1.just do it!' 中 slogan[0] 等于 '1' ,而 name[0] 等于 '耐' 。使用 slogan[0] 和 name[0] 来作为判断条件,是为了使得每个品牌都能够绑定一条对应的口号。

大神,红色部分文字,我觉得而 name[0] 也应该等于 '1'才对,也就是说当list1和list2的序号对上的时候才匹配并打印


不知道我的理解有无错误?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-4 21:36:15 | 显示全部楼层
本帖最后由 lzb1001 于 2023-5-4 23:53 编辑
isdkz 发表于 2023-5-4 20:24
1. 是的,小甲鱼推荐避免使用 + 连接符拼接字符串,因为它会产生新的字符串对象,对内存和性能不友好。但在 ...


感谢大神指点,我的理解和总结如下:

# name、slogan是自命名,用其他命名也可

# name已包含序号

# slogan[2:]采用分片方式表示只取slogan第三位字符开始到结束的所有字符,不要序号和点.,也可采用str.split()方法利用点.进行字符串分隔然后取后面的部分即slogan.split('.')[-1]

# name + ':' + slogan[2:]采用连接符+拼接字符串,组成格式:序号. 品牌:口号,也可采用str.join()方法即':'.join([name, slogan[2:]])或':'.join([name, slogan.split('.')[-1]]),更可采用语法更简洁且性能更好的f-string格式化字符串方法即f'{name}:{slogan[2:]}'或f"{name}:{slogan.split('.')[-1]}",注意:最后这个因涉及嵌套引号,所以最外层应使用双引号!

# 先遍历口号,再遍历品牌,结果将按口号的先后顺序排列,因口号已按序号排列,所以结果也将按顺序排列。也就是说哪个遍历排在列表推导式的前面,结果就将按它的排列顺序排序。

# slogan[0]和name[0]是取口号和品牌的第一个字符即序号,slogan[0] == name[0]判断是否一致是为了在口号和品牌之间建立一一对应的关联关系,注意:list2中品牌列表虽排列无序,但其实每个品牌的序号和list1中该品牌使用口号的序号其实一一对应
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-4 21:59:06 | 显示全部楼层
lzb1001 发表于 2023-5-4 20:51
(2) slogan[0] 和 name[0] 分别指的是每条口号(slogan)和品牌名称(name)的第一个字符。例如 '1.jus ...

对于第一个问题,您的理解是正确的。slogan[0] 和 name[0] 分别指代每个元素字符串的第一个字符。

对于第二个问题,您可能有些误解。name[0] 指代的是 list2 中元素字符串的第一个字符,而不是序号。所以对于这个例子来说,name[0] 等于 '耐',因为它是 "耐克" 这个字符串的第一个字符,与 "1. just do it!" 中的 slogan[0] 不同,后者是字符串 '1'。使用 slogan[0] 和 name[0] 来比较,是为了判断 list1 和 list2 中的元素是否匹配,以便绑定口号和品牌。

对于第三个问题,您的理解是不完全正确的。slogan[0] == name[0] 的目的是将两个列表中相应位置上的元素进行匹配,从而建立一个口号和品牌名称之间的联系。而生成结果按照 1-4 的顺序排列,则是由于在创建列表时就是按照这样的顺序放置各个元素的,从而导致输出结果也遵循着相同的顺序。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-4 23:22:19 | 显示全部楼层
isdkz 发表于 2023-5-4 20:24
1. 是的,小甲鱼推荐避免使用 + 连接符拼接字符串,因为它会产生新的字符串对象,对内存和性能不友好。但在 ...

list3 = [name + ':' + slogan[2:] for slogan in list1 for name in list2 if slogan[0] == name[0]]

请问上面如何用f-string的形式来实现拼接呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-4 23:25:59 | 显示全部楼层
lzb1001 发表于 2023-5-4 23:22
list3 = [name + ':' + slogan[2:] for slogan in list1 for name in list2 if slogan[0] == name[0]]
...

使用 f-string 的形式,可以将 list3 的列表推导式修改为:
list3 = [f"{name}:{slogan[2:]}" for slogan in list1 for name in list2 if slogan[0] == name[0]]

这将使用 f-string 实现字符串的拼接,语法更简洁且性能更好。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-4 23:35:27 | 显示全部楼层
sfqxx 发表于 2023-5-4 21:59
对于第一个问题,您的理解是正确的。slogan[0] 和 name[0] 分别指代每个元素字符串的第一个字符。

对 ...

对于第二个问题,您可能有些误解。name[0] 指代的是 list2 中元素字符串的第一个字符,而不是序号。所以对于这个例子来说,name[0] 等于 '耐',因为它是 "耐克" 这个字符串的第一个字符,与 "1. just do it!" 中的 slogan[0] 不同,后者是字符串 '1'。使用 slogan[0] 和 name[0] 来比较,是为了判断 list1 和 list2 中的元素是否匹配,以便绑定口号和品牌。

大神,冒昧问下:

slogan[0]是指口号字符串“1.Just do it!”中的起始字符即序号‘1’,

如果name[0] 不是指品牌字符串“1.耐克”中的起始字符即序号‘1’,而是等于 '耐'的话,

那python编译器如何将口号字符串“1.Just do it!”与品牌字符串“1.耐克”关联起来呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-4 23:55:35 | 显示全部楼层
isdkz 发表于 2023-5-4 23:25
使用 f-string 的形式,可以将 list3 的列表推导式修改为:

谢谢,

我检查了自己的代码,发现居然是漏了右边的引号,难怪一直提示错误
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 09:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表