可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Say I have a Python list like this:
letters = ['a','b','c','d','e','f','g','h','i','j']
I want to insert an 'x' after every nth element, let's say three characters in that list. The result should be:
letters = ['a','b','c','x','d','e','f','x','g','h','i','x','j']
I understand that I can do that with looping and inserting. What I'm actually looking for is a Pythonish-way, a one-liner maybe?
回答1:
I've got two one liners.
Given:
>>> letters = ['a','b','c','d','e','f','g','h','i','j']
Use enumerate
to get index, add 'x'
every 3rd letter, eg: mod(n, 3) == 2
, then concatenate into string and list()
it.
>>> list(''.join(l + 'x' * (n % 3 == 2) for n, l in enumerate(letters)))
['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j']
But as @sancho.s points out this doesn't work if any of the elements have more than one letter.
Use nested comprehensions to flatten a list of lists(a), sliced in groups of 3 with 'x'
added if less than 3 from end of list.
>>> [x for y in (letters[i:i+3] + ['x'] * (i < len(letters) - 2) for
i in xrange(0, len(letters), 3)) for x in y]
['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j']
(a) [item for subgroup in groups for item in subgroup]
flattens a jagged list of lists.
回答2:
Try this
i = n
while i < len(letters):
letters.insert(i, 'x')
i += (n+1)
where n
is after how many elements you want to insert 'x'
.
This works by initializing a variable i
and setting it equal to n
. You then set up a while
loop that runs while i
is less then the length of letters
. You then insert 'x'
at the index i
in letters
. Then you must add the value of n+1
to i
. The reason you must do n+1
instead of just n
is because when you insert an element to letters
, it expands the length of the list by one.
Trying this with your example where n
is 3 and you want to insert 'x'
, it would look like this
letters = ['a','b','c','d','e','f','g','h','i','j']
i = 3
while i < len(letters):
letters.insert(i, 'x')
i += 4
print letters
which would print out
['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j']
which is your expected result.
回答3:
Although using list.insert()
in a for
loop seems to be more memory efficient, in order to do it in one-line, you can also append the given value at the end of every equally divided chunks split on every nth
index of the list.
>>> from itertools import chain
>>> n = 2
>>> ele = 'x'
>>> lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(chain(*[lst[i:i+n] + [ele] if len(lst[i:i+n]) == n else lst[i:i+n] for i in xrange(0, len(lst), n)]))
[0, 1, 'x', 2, 3, 'x', 4, 5, 'x', 6, 7, 'x', 8, 9, 'x', 10]
回答4:
A pretty straightforward method:
>>> letters = ['a','b','c','d','e','f','g','h','i','j']
>>> new_list = []
>>> n = 3
>>> for start_index in range(0, len(letters), n):
... new_list.extend(letters[start_index:start_index+n])
... new_list.append('x')
...
>>> new_list.pop()
'x'
>>> new_list
['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j']
You can also use the grouper
recipe from the itertools documentation for the chunking.
回答5:
I want to add a new element per item.
How about this ?
a=[2,4,6]
for b in range (0,len(a)):
a.insert(b*2,1)
a is now
[1, 2, 1, 4, 1, 6]
回答6:
This is an old topic, but it lacks the easiest, most "pythonic" solution, imo. It is no more than an extension to part 2 of Mark Mikofski's accepted answer that arguably improves readability (and therefore makes it more pythonic).
>>> letters = ['a','b','c','d','e','f','g','h','i','j']
>>> [el for y in [[el, 'x'] if idx % 3 == 2 else el for
idx, el in enumerate(letters)] for el in y]
['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j']
回答7:
l = ['a','b','c','d','e','f','g','h','i','j']
[ l.insert(n+(n+1)*i, 'x') for i in range(len(l)/n) ]
print l