问题
I have a python script with this list:
blocks = [
"item-1",
"item-2",
"item-3.0;item-3.1;item-3.2"
]
I have tried this:
for (i, block) in enumerate(blocks):
if ";" in block:
[blocks.insert(i, c) for c in block.split(";")]
else:
blocks.insert(i, block)
To get this:
blocks = [
"item-1",
"item-2",
"item-3.0",
"item-3.1",
"item-3.2"
]
Unfortunately my code keeps overwriting the the elements in the list, and I'm left with this:
blocks = [
"item-1",
"item-2",
"item-3.2"
]
How can I modify the script to allow me to split a string inside of a list and then insert the new sub-strings into the position of the original string without overwriting the other elements in the list?
回答1:
It would probably be easier to make a new list:
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']
回答2:
split will return a list, you don't need to check if ';' is in the block:
In [34]: [ii.split(';') for ii in blocks]
Out[34]: [['item-1'], ['item-2'], ['item-3.0', 'item-3.1', 'item-3.2']]
So now the only thing you need is to add all the list together, with the function sum.
sum( [ii.split(';') for ii in blocks] , [])
回答3:
You may achieve this via using nested list comprehension expression:
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(';')]
where content hold by my_list
will be:
['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']
回答4:
You can create a new list to hold the results instead of modifying the original list while looping through it:
result = []
for block in blocks:
result.extend(block.split(";"))
result
# ['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']
Inspired by @Jblasco's answer, you can also use 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']
回答5:
in place editing of lists while iterating over it is not a good idea.
As the other answers say, make a new list. If you're into list comprehensions (and make your head explode a little), try this:
blocks = [
"item-1",
"item-2",
"item-3.0;item-3.1;item-3.2"
]
[substr for block in blocks for substr in block.split(';')]
回答6:
';'.join(blocks).split(';')
out:
['item-1', 'item-2', 'item-3.0', 'item-3.1', 'item-3.2']
Just join
the list together and split
again.
And in the Document, sum
a list is not recommended:
For some use cases, there are good alternatives to sum(). The preferred, fast way to concatenate a sequence of strings is by calling ''.join(sequence). To add floating point values with extended precision, see math.fsum(). To concatenate a series of iterables, consider using
itertools.chain()
.
来源:https://stackoverflow.com/questions/41700349/how-to-split-strings-inside-a-list-by-given-delimiter-and-flatten-the-sub-string