Python:列表理解与生成器表达式

Python!自从这次大流行以来,我们经常听到这个名字。从小孩到我们(开发人员),所有人都在学习和开发使用它的软件和程序。那么,python有那么容易吗?

与其他编程语言(如C/C++/Java/Ruby等)相比,这可能很容易,但并不像访问 Spotify 或 Instagram(使用 Python 开发)那么容易。它有相当多的挑战和困难,但这并不意味着你不能学习它。学习 python 是一门艺术,我是你的艺术家,我将向你展示一个小技巧,以确保你的程序使用List comprehensionsGenerator 表达式顺利运行。

所以当我开始学习 Python 的时候,我遇到的第一件事就是FOR 循环,用的很多。起初,我发现它们很复杂而且有点困难(作为初学者)。我不喜欢的另一件事是WHILE 循环,这让我更加困惑。有人告诉我,FOR 循环可以做什么,WHILE 循环可以做同样的事情,反之亦然。我脑子里突然冒出一个问题…… Bhai agar WHILE loop FOR loop ka kaam karra hai 加上额外的 kaam kar raha hai 为什么不直接使用它?嗯,答案很简单,你需要解决很多复杂的问题才能使 WHILE 循环工作,它占用的空间比 FOR 多得多(空间在某种意义上......增加了代码的长度。代码应该是更短,因为对于程序员来说,更短更甜)。所以,我通过了它并学习了如何使用 FOR 循环。

在此之后,我遇到了 LIST。一切都很顺利,直到我开始学习列表推导式。它只是让我大吃一惊。由于使用前后条件构建列表推导式的多种方法以及更多方法,这令人困惑。现在,这开始让我头疼。(编程从来都不是一件容易的事)。我费了好大劲才弄明白,终于明白了。

所以现在,让我们离开我的故事,让我们看看什么是列表推导式。

列表理解:

当您想根据某个现有循环的值创建新循环时,与 for 循环相比,列表推导式为我们提供了更短的语法。

当我们想要创建一个新列表时,会使用列表理解,该列表的值取决于程序中某个现有列表的值。

它有3个好处:

  1. 它使您的代码更短。
  2. 这很容易理解。
  3. 自动创建一个列表,无需您要求它制作一个。

现在我们将看到一些示例以更好地理解。

例 1:这里,我们使用了一个 for 循环,代码看起来很大。编写大型程序会浪费时间,因为我们必须编写很多额外的行。

names = ["vidhanshu","vidit","sobhan","laksh"][name for name in names if name[0] == 'v']<['vidhanshu', 'vidit']>

或者

我们用一行代码做了同样的事情。

names = ["vidhanshu","vidit","sobhan","laksh"][name for name in names if name[0] == 'v']<['vidhanshu', 'vidit']>

例 2:编写一个程序,当我们传入数字 1-10 时,它会打印出小于 6 的数字。

等等……自己尝试一下,然后参考下面的内容。

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

您可以通过这两种方法解决上述问题,但推荐使用列表理解。

eemp = []for num in range(10):    if num < 6:        eemp.append(num)print(eemp)<[0, 1, 2, 3, 4, 5]>

或者

eemp = [num for num in range(10) if num <6]print(eemp)<[0, 1, 2, 3, 4, 5]>

使用列表推导式,我们甚至可以将输出作为布尔值。这可能用于一些内置函数,或者如果我们需要访问程序中其他地方的布尔值。

喜欢:

emp = [num < 6 for num in range(10)]print(emp)<[True, True, True, True, True, True, False, False, False, False]>names = ["vidhanshu","vidit","sobhan","laksh"]empty = [name[0] == 'v' for name in names]print(empty)<[True, True, False, False]>

让我向您介绍两个内置函数,其中可以使用列表推导式中的布尔值。

  1. 全部
  2. 任何

ALL:这是一个内置函数,如果所有可迭代项都是真值,它将返回 True。即使可迭代对象为空,它也会返回 True。

all([num for num in [0,1,2,3]])# 0 is always considered False. Since we have a single False element the whole list becomes False.<False>all([])# As mentioned above, an empty list will return True. (list is iterable)<True>all([num < 6 for num in range(6)])# Range(6) means all the numbers from 0–5. And all these numbers are less than 6, thus True.<True>all([num < 6 for num in range(10)])# Range(10) means all the numbers from 0–9. This even includes numbers greater than 6 which is False, thus False.<False>

我希望所有功能都清楚。

任何:任何猜测????

是的,相信很多人都猜对了!

ANY 又是另一个内置函数,如果列表中的“任何一个”元素为真,则输出 True。这里当我们发送一个空的可迭代对象时它返回 False。

any([num for num in [0,1,2,3]])# Here 0 is falsy but doesn't matter, 1 is the truth so it'll return True only.<True>any([])# As mentioned above, empty iterable will be False.<False>any([num < 6 for num in range(10)])# range(10) is from 0–9. Up to 5 It's True, hence the output will be True.<True>
any([num % 2 == 0 for num in [10,2,16,18,21]])# 10,2,16,18 are divisible by 2 gives remainder 0, hence True (doesn't matter if 21 is divisible or not.)<True>any([num % 2 == 1 for num in [10,2,16,18,21]])# 21, when divided by 2, gives 1 as remainder. Hence True<True>any([num % 2 == 2 for num in [10,2,16,18,21]])# None of those divided by 2 will give the remainder as 2. Hence False<False>

在处理这些功能时,我犯了一个错误。IE:

any(num % 2 == 1 for num in [10,2,16,18,21])<True>
any(num % 2 == 2 for num in [10,2,16,18,21])<False>
all(num < 6 for num in range(10))<False>
names = ["vidhanshu","vidit","sobhan","laksh"]all(name[0] == 'v' for name in names)<False>

在所有这些示例中,我将它们从列表中删除,并将它们放在 ALL 和 ANY 的括号之间。

我观察到结果没有变化。BUT BUT BUT……变化在于所使用的方法或语法。

只打印括号和里面的内容得到的输出是:

names = ["vidhanshu","vidit","sobhan","laksh"](name[0] == 'v' for name in names)<generator object <genexpr> at 0x7f6548d2bbd0>

生成器对象。 是的,这是另一种使用的语法。它被称为发电机。

发电机表达

生成器类似于函数,它们使用“yield()”代替“return()”来返回结果。作为实现迭代器的工具,它更强大。

各种其他生成器表达式可以类似于列表推导式进行编码,但我们使用括号代替方括号。

generator = (num ** 3 for num in range(5))for num in generator:    print (num)<0 
 1 
 8 
 27 
 64>
generator = ([num ** 3 for num in range(5)])print(generator)<[0, 1, 8, 27, 64]>
generator = (num ** 3 for num in range(5))print(list(generator))<[0, 1, 8, 27, 64]>

这两者之间的唯一区别是我们在第二个打印时将 var “generator” 转换为列表,并且我们使用列表推导式,默认情况下将其保存到列表中。

那么列表推导式和生成器表达式有什么区别呢?

有两个区别:

  1. 时间
  2. 内存效率

列表推导速度更快,而生成器的内存效率更高。

%timeit listcomp = sys.getsizeof([x*10 for x in range(500)])%timeit generatorexp = sys.getsizeof(x*10 for x in range(500))<10000 loops, best of 5: 38.6 µs per loop 
The slowest run took 6.25 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000000 loops, best of 5: 771 ns per loop>import syslistcomp = sys.getsizeof([x*10 for x in range(500)])generatorexp = sys.getsizeof(x*10 for x in range(500))print(f"List comprehension takes {listcomp} bytes")print(f"Generator expression takes {generatorexp} bytes")<List comprehension takes 4280 bytes 
Generator expression takes 128 bytes>

如果您所做的只是迭代一次,请使用生成器。如果您只想存储和使用生成的结果,请使用列表推导式。

使我成为优秀 Python 开发人员的 5 个 Python 技巧

 每个程序员都需要停止做这 7 件事

面向新手的应用程序开发和编码技巧

你选择什么并不重要。两者都有优点和缺点。你只需要担心你的代码运行缓慢。只有这样,您才必须仔细选择是使用生成器还是列表推导式。

使用生成器,您可以以任何可迭代格式(字典、元组或列表)打印或存储值,而在列表理解中,它默认存储为列表。

对于 Python 的某些部分,您会发现它有点令人困惑,但是随着您的前进,您会觉得上一部分很容易。这是因为python是一种易于使用的语言。但是,没有什么事情总是容易的,一切都从复杂开始,然后变得容易。

冷静,别担心。Python 将是你的小菜一碟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pxr007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值