如何按给定分隔符拆分列表中的字符串并展开子字符串列表

3

我有一个Python脚本,其中包含以下列表:

blocks = [
  "item-1",
  "item-2",
  "item-3.0;item-3.1;item-3.2"
]

我尝试过这个:

for (i, block) in enumerate(blocks):
  if ";" in block:
    [blocks.insert(i, c) for c in block.split(";")]
  else:
    blocks.insert(i, block)

为了得到这个:
blocks = [
  "item-1",
  "item-2",
  "item-3.0",
  "item-3.1",
  "item-3.2"
]

很不幸,我的代码一直在覆盖列表中的元素,最终留下了这样的结果:
blocks = [
  "item-1",
  "item-2",
  "item-3.2"
]

如何修改脚本,以便允许我在列表内拆分字符串,并将新的子字符串插入到原始字符串的位置,而不会覆盖列表中的其他元素?


为什么不创建一个新列表,将它们全部添加到新列表中。 - ᴀʀᴍᴀɴ
6个回答

8
您可以通过使用嵌套列表推导式表达式来实现此操作:
blocks = [
   "item-1",
   "item-2",
   "item-3.0;item-3.1;item-3.2"
]

my_list = [a for b in blocks for a in b.split(';')]

my_list中包含的内容将是:

['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']

5

split函数会返回一个列表,你不需要检查分号是否在块中:

In [34]: [ii.split(';') for ii in blocks]
Out[34]: [['item-1'], ['item-2'], ['item-3.0', 'item-3.1', 'item-3.2']]

现在你只需要使用函数 sum 将所有列表元素相加即可。

sum( [ii.split(';') for ii in blocks] ,  [])

不建议使用sum()。您可以使用嵌套列表推导式代替。 - wjandrea
1
同意,对于长列表,这并不高效。我发现嵌套的列表推导式...很难理解 :p - Jblasco

4

最好创建一个新列表:

blocks = [
  "item-1",
  "item-2",
  "item-3.0;item-3.1;item-3.2"
]

new_blocks = []

for block in blocks:
    for c in block.split(";"):
        new_blocks.append(c)

 # new_blocks = ['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']

3
你可以创建一个新的列表来保存结果,而不是在循环过程中修改原始列表:
result = []
for block in blocks:
    result.extend(block.split(";"))

result
# ['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']

受@Jblasco答案的启发,您也可以使用chain:
from itertools import chain
list(chain.from_iterable(block.split(';') for block in blocks))

# ['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']

0

在迭代列表时进行就地编辑并不是一个好主意。

正如其他答案所说,创建一个新列表。如果您喜欢列表理解(并且让您的头爆炸一点),可以尝试这个:

blocks = [
  "item-1",
  "item-2",
  "item-3.0;item-3.1;item-3.2"
]
[substr for block in blocks for substr in block.split(';')]

0
';'.join(blocks).split(';')

输出:

['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']

只需将列表join在一起,然后再进行split

文档中,不建议对列表进行sum

对于某些用例,有好的替代方案可以取代sum()。连接序列字符串的首选快速方法是调用''.join(sequence)。要添加具有扩展精度的浮点值,请参见math.fsum()。如果要连接一系列可迭代对象,请考虑使用itertools.chain()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接