在 Python 列表中的每个第 n 个元素之后插入元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31040525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Insert element in Python list after every nth element
提问by Hasan Iqbal
Say I have a Python list like this:
假设我有一个这样的 Python 列表:
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:
我想在每个第 n 个元素后插入一个“x”,假设该列表中的三个字符。结果应该是:
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?
我知道我可以通过循环和插入来做到这一点。我实际上正在寻找的是一种 Pythonish 方式,也许是一种单线方式?
采纳答案by Mark Mikofski
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 3rdletter, eg:mod(n, 3) == 2
, then concatenate into string andlist()
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.spoints outthis 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']
使用
enumerate
获得指数,增加'x'
每3次字母,如:mod(n, 3) == 2
,然后连接成字符串和list()
它。>>> 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']
使用嵌套理解来展平列表(a)的列表,以 3 为一组切片,
'x'
如果距离列表末尾少于3,则添加。>>> [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.
(a) 展[item for subgroup in groups for item in subgroup]
平一个锯齿状的列表。
回答by michaelpri
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'
.
这里n
是你要多少元素插入之后'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.
这通过初始化一个变量i
并将其设置为等于n
. 然后设置一个while
循环,该循环运行 whilei
小于 的长度letters
。然后,您插入'x'
该指数i
在letters
。然后您必须添加n+1
to的值i
。您必须这样做n+1
而不是仅仅这样做的原因n
是因为当您向 插入一个元素时letters
,它会将列表的长度扩大一。
Trying this with your example where n
is 3 and you want to insert 'x'
, it would look like this
用你的例子尝试这个,其中n
是 3 并且你想插入'x'
,它看起来像这样
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.
这是您的预期结果。
回答by hongshuning
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
回答by Mike Graham
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.
您还可以使用grouper
itertools 文档中的配方进行分块。
回答by ozgur
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.
尽管list.insert()
在for
循环中使用似乎内存效率更高,但为了在一行中执行此操作,您还可以nth
在列表的每个索引上拆分的每个等分块的末尾附加给定值。
>>> 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]
回答by Tim Seed
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]
回答by John Paper
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 answerthat arguably improves readability (and therefore makes it more pythonic).
这是一个古老的话题,但它缺少最简单、最“pythonic”的解决方案 imo。它只不过是Mark Mikofski 已接受答案的第2 部分的扩展,可以说提高了可读性(因此使其更加 Python 化)。
>>> 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']
回答by ChrisFreeman
While Mark Mikofski's answerworks, there is a faster solution by assigning slices:
虽然Mark Mikofski的答案有效,但通过分配切片有一个更快的解决方案:
import string
# The longer the list the more speed up for list3
# letters = ['a','b','c','d','e','f','g','h','i','j']
letters = list(string.ascii_letters)
print("org:", letters)
# Use enumerate to get index, add 'x' every 3rd letter, eg: mod(n, 3) == 2, then concatenate into string and list() it.
list1 = list(''.join(l + 'x' * (n % 3 == 2) for n, l in enumerate(letters)))
print("list1:", list1)
%timeit list(''.join(l + 'x' * (n % 3 == 2) for n, l in enumerate(letters)))
# 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.
list2 = [x for y in (letters[i:i+3] + ['x'] * (i < len(letters) - 2) for i in range(0, len(letters), 3)) for x in y]
print("list2:", list2)
%timeit [x for y in (letters[i:i+3] + ['x'] * (i < len(letters) - 2) for i in range(0, len(letters), 3)) for x in y]
# Use list slice assignments
len_letters = len(letters)
len_plus_x = ll // 3
list3 = [None for _ in range(len_letters + len_plus_x)]
list3[::4] = letters[::3]
list3[2::4] = letters[2::3]
list3[1::4] = letters[1::3]
list3[3::4] = ['x' for _ in range(len_plus_x)]
print("list3:", list3)
%timeit ll = len(letters); lp = ll//3; new_letters = [None for _ in range(ll + lp)]; new_letters[::4] = letters[::3]; new_letters[2::4] = letters[2::3]; new_letters[1::4] = letters[1::3]; new_letters[3::4] = ['x' for _ in range(lp)]
produces (using jupyter notebook)
产生(使用 jupyter notebook)
org: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
list1: ['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j', 'k', 'l', 'x', 'm', 'n', 'o', 'x', 'p', 'q', 'r', 'x', 's', 't', 'u', 'x', 'v', 'w', 'x', 'x', 'y', 'z', 'A', 'x', 'B', 'C', 'D', 'x', 'E', 'F', 'G', 'x', 'H', 'I', 'J', 'x', 'K', 'L', 'M', 'x', 'N', 'O', 'P', 'x', 'Q', 'R', 'S', 'x', 'T', 'U', 'V', 'x', 'W', 'X', 'Y', 'x', 'Z']
13 μs ± 1.09 μs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
list2: ['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j', 'k', 'l', 'x', 'm', 'n', 'o', 'x', 'p', 'q', 'r', 'x', 's', 't', 'u', 'x', 'v', 'w', 'x', 'x', 'y', 'z', 'A', 'x', 'B', 'C', 'D', 'x', 'E', 'F', 'G', 'x', 'H', 'I', 'J', 'x', 'K', 'L', 'M', 'x', 'N', 'O', 'P', 'x', 'Q', 'R', 'S', 'x', 'T', 'U', 'V', 'x', 'W', 'X', 'Y', 'x', 'Z']
13.7 μs ± 336 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
list3: ['a', 'b', 'c', 'x', 'd', 'e', 'f', 'x', 'g', 'h', 'i', 'x', 'j', 'k', 'l', 'x', 'm', 'n', 'o', 'x', 'p', 'q', 'r', 'x', 's', 't', 'u', 'x', 'v', 'w', 'x', 'x', 'y', 'z', 'A', 'x', 'B', 'C', 'D', 'x', 'E', 'F', 'G', 'x', 'H', 'I', 'J', 'x', 'K', 'L', 'M', 'x', 'N', 'O', 'P', 'x', 'Q', 'R', 'S', 'x', 'T', 'U', 'V', 'x', 'W', 'X', 'Y', 'x', 'Z']
4.86 μs ± 35.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
回答by Sorin
It's worth stating the simple implementation too:
也值得说明简单的实现:
letters = ['a','b','c','d','e','f','g','h','i','j']
i = 3 #initial step
while i < len(letters):
letters.insert(i,'x')
i = i + 3 + 1 #increment step by one for every loop to account for the added element
It does use basic looping and inserting, but it also looks much simpler and comfortable to read than the one-liner examples, which IMHO makes it more Pythonishas requested in the first place.
它确实使用了基本的循环和插入,但与单行示例相比,它看起来也更简单、更易于阅读,恕我直言,它首先按照要求使其更像Python 风格。