列表理解拆分循环变量

2024-04-27 12:30:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找出是否有一种方法可以将列表理解的每个迭代的值只分割一次,但在输出中使用两次。

例如,我要解决的问题是,我有一个字符串:

a = "1;2;4\n3;4;5"

我想表演一下:

>>> [(x.split(";")[1],x.split(";")[2]) for x in a.split("\n") if x.split(",")[1] != 5]
[('2', '4'), ('4', '5')]

不需要分三次跑。所以类似这样的东西(这显然是无效的语法,但希望足够让消息通过):

[(x[1],x[2]) for x.split(";") in a.split("\n") if x[1] != 5]

在这个问题上,我不是在寻找获得字符串第2列和第3列的奇特方法。这只是提供一个具体例子的一种方式。我当然可以举个例子:

[x.split(";")[1:3] for x in a.split("\n")]

我想到的可能的解决办法是:

  1. 不使用列表理解
  2. 保持原样
  3. 使用csv.DictReader,命名我的列和StringIO之类的东西来给它输入。

这通常是一个很好的模式,可以使用,而不是一个特定的案例,所以很难回答“为什么你想这样做”或“这是为了什么”之类的问题

更新:在阅读了下面的解决方案后,我去做了一些速度测试。在我的基本测试中,我发现提供的解决方案比上面的简单解决方案快35%。


Tags: csv方法字符串in消息列表forif
2条回答

启动Python 3.8,并引入assignment expressions (PEP 572):=运算符),可以在列表理解中使用局部变量,以避免调用同一表达式的两次:

在我们的例子中,如果parts[1]不等于5,我们可以将line.split(';')的求值命名为变量parts,同时使用表达式的结果过滤列表,从而重用parts来生成映射值:

# text = '1;2;4\n3;4;5'
[(parts[1], parts[2]) for line in text.split('\n') if (parts := line.split(';'))[1] != 5]
# [('2', '4'), ('4', '5')]

可以在生成器表达式周围使用列表理解:

[(x[1],x[2]) for x in (x.split(";") for x in a.split("\n")) if x[1] != 5]

相关问题 更多 >