列表推导分裂循环变量

时间:2012-04-25 03:26:30

标签: python split list-comprehension

我试图找出是否有一种方法只将列表推导的每次迭代的值拆分一次,但在输出中使用它两次。

作为我想解决的问题的一个例子,我有字符串:

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,为其提供输入。
  4. 这大部分是一个很好的模式,能够使用而不是特定的案例,因此很难回答“你为什么要这样做”或“这是什么”的问题

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

2 个答案:

答案 0 :(得分:21)

您可以使用围绕生成器表达式的列表推导:

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

答案 1 :(得分:0)

Python 3.8开始并引入assignment expressions (PEP 572):=运算符),可以在列表推导中使用局部变量,以避免两次调用相同的表达式:< / p>

在我们的例子中,如果line.split(';')不等于{{1,则可以使用表达式的结果来过滤列表,同时可以将parts的计算结果命名为变量parts[1]。 }};并因此重新使用5来产生映射值:

parts