【问题标题】:Best way to split every nth string element and merge into array?拆分每个第 n 个字符串元素并合并到数组中的最佳方法?
【发布时间】:2014-04-06 01:20:37
【问题描述】:

抱歉标题含糊不清,但很难简明扼要地解释。

基本上,假设我有一个列表(在 Python 中),如下所示:

['a', 'b', 'c\nd', 'e', 'f\ng', 'h', 'i']

由此,我想得到这个:

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

我想这样做的一种方法是像这样使用reduce

reduce(lambda x, y: x + y.split('\n'), lst, [])

但我认为这不是很有效,因为它没有利用我们知道每个第 n 个元素都有分隔符的事实。有什么建议吗?

编辑:有关如何构造数组的更多背景信息,这可能是问题所在。

我的文本格式为:

Ignorable line
Field name 1|Field name 2|Field name 3|Field name 4
Value 1|Value 2|Value 3|Value 4
Value 1|Value 2|Value 3|Value 4
...

我们可以有任意数量的字段名称,并且总是有与在线字段名称相同数量的值。请注意,我们可以在值中添加新行。我们只知道会用'|'隔开。所以我们可以有

Value 1|This is an long
value that extends over multiple
lines|Value 3|Value 4

我目前的做法是使用s.split('\n', 2),以便我们在它们自己的字符串中获取字段名称,并在它们自己的字符串中获取值。然后,当用'|'分割值时,我们得到了我最初提到的形式的列表。

【问题讨论】:

  • 你是什么意思每第 n 个元素......看起来你的 n 从 3 变为 2......除了它可能很快......除非它实际上不是,但在那种情况下你会知道那是你的瓶颈....过早的优化是万恶之源
  • 在示例中,\n 总是跟在第 3 项之后(c 是字母表的第 3 个字母;f 是第 6 个)。我很好奇是什么导致您以这种格式获取初始列表。如果您更改构建原始列表的方式,也许代码会更清晰......这感觉就像是解析器损坏的解决方法。
  • @ramcdougal 这可能不是构建该列表的最佳方式。我将更新帖子,说明我是如何以这种形式获得的。
  • 如果您从一个字符串s 中的行和行开始,为什么不删除换行符,然后在竖线处拆分。类似items=s.replace('\n', ' ').split('|')
  • 你的意思是 `items=s.replace('\n', ' ').split('|') 吗?因为我按照这些思路做了一些事情,事情变得更快了。谢谢!

标签: python list


【解决方案1】:

您可以通过('\n'.join(lst)).split() 获得第二个列表。

In [17]:

%timeit reduce(lambda x, y: x + y.split('\n'), lst, [])
100000 loops, best of 3: 9.64 µs per loop
In [18]:

%timeit ('\n'.join(lst)).split() 
1000000 loops, best of 3: 1.09 µs per loop

感谢@Joran Beasley 建议split() 胜过split('\n')

编辑

现在我看到您更新的问题,我认为我们可以避免一开始就陷入这种情况,请参阅(使用re):

In [71]:

L=re.findall('([^|]+)\|',
           ''.join(['|'+item+'|' if item.count('|')==3 else item for item in S.split('\n')[1:]])+'|')
In [72]:

zip(*[L[i::4] for i in range(4)]) #4 being the number of fields.
Out[72]:
[('Field name 1', 'Field name 2', 'Field name 3', 'Field name 4'),
 ('Value 1', 'Value 2', 'Value 3', 'Value 4'),
 ('Value 1',
  'This is an longvalue that extends over multiplelines',
  'Value 3',
  'Value 4')]

最初看起来像 SAS 的数据集,对吗?

【讨论】:

  • 这肯定要快得多,但其他元素中也可能有新行(可能是多行,数量未知)。我会用这些信息更新帖子。
  • 有机会解决问题吗?如果没有,请参阅编辑。
  • 我做了,但这也可以。我正在解析的输出实际上是 WQL 查询的请求,使用的是 Linux 上的 wmic 实用程序。见aldeid.com/wiki/Wmic-linux
【解决方案2】:

过早的优化是万恶之源

如果你真的因为这段代码而遇到性能问题,那是一回事,但我怀疑你是。

当你优化时,你通常会牺牲可读性,如果是我,我会怎么做

list(itertools.chain(*[item.split() for item in lst]))

很清楚你在做什么

【讨论】:

  • 嗨乔兰,你确定这会奏效吗?我觉得应该是list(itertools.chain(*[item.split() for item in lst]))
  • 啊,你完全正确,你的答案在清晰度方面更好,我认为无论如何(“虽然 id 可能只是使用没有分隔符的正常拆分,但是 meh)
猜你喜欢
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 1970-01-01
  • 2021-10-22
  • 2013-01-02
  • 2019-06-29
  • 2022-11-22
相关资源
最近更新 更多