列表理解中迭代器链接的替代方法?

Alternative ways for iterator chaining in List Comprehension?

我想在列表理解中将两个或多个不同的迭代器链接在一起。

假设我想将大小写字母组合成一个列表。我原来的做法是这样的,

lst1 = [chr(i) for i in range(97,123)]
lst2 = [chr(i) for i in range(65,91)]
lst = lst1+lst2

但是我认为必须有一些其他方法可以在一行中很好地完成此操作,然后我将其与 itertools 模块一起使用,

lst = [chr(i) for i in itertools.chain(range(97,123), range(65,91))]

最后我也想到了元组拆包,

lst = [chr(i) for i in (*range(97,123), *range(65,91))]

与其他两种方法相比,Itertools 速度较慢(元组解包是最快的一种)

例如,第一个范围和第二个范围中的字符组成列表

>>> lst1
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

>>> lst2
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

我希望它们只与 1 个迭代器合并,而不是两个单独的迭代器。下面给出了合并列表的示例,其中使用了 2 个不同的值范围,

>>> lst
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

有什么方法可以改进或更改设计吗?

您已找到正确的解决方案。

注意:itertools.chain 可能稍微慢一些,但它的优点是(有效地)零内存开销,我一般会推荐它。 range 已经(有效地)为零内存开销,因此将它与 chain 一起使用意味着根本没有有意义的内存开销,而使用解包到 tuple 涉及实现两个 range作为 tuple 没有真正的原因。如果大小永远不会增加,那么无论如何,但如果输入可能是可变长度,chain 比在内存中实现无限迭代更安全。

当然,对于您的具体情况,显而易见的解决方案(可读性更高)是:

 import string

 lst = list(string.ascii_letters)

这可能不像从包中提取的列表那样整洁string但是它确实通过采用两个集合的并集创建一个可迭代来解决你的问题并且应该也非常有效。

>>> [chr(i) for i in set(range(97,123)).union(range(65,91))]
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']