我正在尝试按列表中的特定项目剪切列表,例如,我有一个这样的列表:
down = ["a", "b", "c", "d", "b", "e", "r"]
我想要的是
[["a", "b"]["c", "d", "b"] ["e", "r"]]
在每次发生"b"
之后被削减。
我写了这样的东西:
down = ["a", "b", "c", "d", "b", "e", "r"]
up = []
while down is not []:
up, down = up.append(down[:(down.index("b") + 1)]), down[(down.index("b") + 1):]
它抛出一个错误:
AttributeError: 'NoneType' object has no attribute 'append'
我不知道怎么了。
答案 0 :(得分:3)
您可以迭代原始列表并将子列表组合在第二个列表中:
k = ["a", "b", "c", "d", "b", "e", "r"]
result = [[]]
for e in k:
if e != "b":
result[-1].append(e)
else:
result[-1].append(e)
result.append([])
if result[-1] == []:
result.pop() # thx iBug's comment
print(result) # [['a', 'b'], ['c', 'd', 'b'], ['e', 'r']]
我认为这比您的代码尝试做的要清楚得多-您的“我想要的["a", "b"]["c", "d", "b"] ["e", "r"]
”不是有效的python。
性能稍差的代码是:
k = ["a", "b", "c", "d", "b", "e", "r"]
b = []
while True:
try:
b_idx = k.index("b")
except:
b.append(k)
break
else:
b,k = b+[k[:b_idx+1]],k[b_idx+1:]
print(b)
但是您需要通过.index()
和try: except
对列表进行更深入的搜索,因此其性能较差,然后仅对列表进行一次迭代即可。
答案 1 :(得分:1)
list.append(elem)
不返回新列表,仅修改原始列表。这就是导致您出错的原因。
在不更改方法的情况下更正代码:
down = ["a", "b", "c", "d", "b", "e", "r"]
up = []
while True:
if 'b' in down: # make sure there is a 'b' in the list
index = down.index("b") # get the index of the first "b"
up.append(down[:index + 1]) # save first sublist in up
down = down [index + 1:] # trim the sublist you already saved
else:
up.append(down) # add the rest of down
break # leave the loop
print(up)
答案 2 :(得分:1)
如果没有itertools
答案,这样的问题会是什么?
在这种情况下,您可以将groupby
与自定义键一起使用,该自定义键可以统计过去'b'
的出现次数:
from itertools import groupby
class CountKey:
def __init__(self, what):
self.what = what
self.count = 0
def __call__(self, item):
count = self.count
if item == self.what:
self.count += 1
return count
up = [list(g) for k, g in groupby(down, CountKey('b'))]
答案 3 :(得分:1)
您可以构造一个索引列表,然后使用列表理解:
down = ["a", "b", "c", "d", "b", "e", "r"]
n = len(down)
idx = [index+1 for index, value in enumerate(down) if value == 'b']
res = [down[i: j] for i, j in zip([0] + idx, idx + ([n] if idx[-1] != n else []))]
# [['a', 'b'], ['c', 'd', 'b'], ['e', 'r']]
如果[n] if idx[-1] != n else []
中的最后一个值为down
,则使用三元语句'b'
来避免空的最终列表。这是一种两遍解决方案,但是使用列表切片,而不是一次显式地追加一项。
答案 4 :(得分:1)
这是一个简单的单线来完成这项工作:
import re
d = ["a", "b", "c", "d", "b", "e", "r"]
s = '(?<=b)'
print ([list(x) for x in re.split(s,"".join(d))])
输出:
[['a', 'b'], ['c', 'd', 'b'], ['e', 'r']]
这里的难点在于将分隔符保留在“左”子列表中。 re.split()
方法可以与积极的前瞻相关联地做到这一点。
答案 5 :(得分:0)
down = ["a", "b", "c", "d", "b", "e", "r"]
poslist = []
for pos, item in enumerate(down):
if item == 'b':
poslist.append(pos)
answerlist = []
for i in range(len(poslist)):
if i == 0:
answerlist.append(down[:poslist[i]+1])
else:
answerlist.append(down[poslist[i-1]+1:poslist[i]+1])
answerlist.append(down[poslist[i]+1:])
print (answerlist)
# [['a', 'b'], ['c', 'd', 'b'], ['e', 'r']]
答案 6 :(得分:0)
down = ["a", "b", "c", "d", "b", "e", "r"]
indices = [i for i, x in enumerate(down ) if x == "b"]
curr=0
master_list=[]
for item in indices:
master_list.append(down[curr:item+1])
print(master_list)
curr=item+1
if curr !=len(down):
master_list.append(down[curr:len(down)])
print(master_list)
答案 7 :(得分:0)
In [59]: k
Out[59]: ['a', 'b', 'c', 'd', 'b', 'e', 'r', 'l', 'f', 'b', 's']
In [60]: indices = [i for i, x in enumerate(k) if x == "b"] # all index of 'b'
In [61]: aa = k[:indices[0]+1] # first list
In [62]: bb = k[indices[len(indices)-1]+1:] # last list
In [63]: for i in range(0, len(indices)-1):
...: print(k[indices[i]+1:indices[i+1]+1]) # remaining list
...:
['c', 'd', 'b']
['e', 'r', 'l', 'f', 'b']
In [64]: aa
Out[64]: ['a', 'b']
In [65]: bb
Out[65]: ['s']
答案 8 :(得分:0)
import re
l = ['a', 'b', 'c', 'd', 'b', 'e', 'r']
split_by = 'b'
pattern = re.compile(r'(.*?{0})'.format(split_by))
split_list = re.split(pattern, ('').join(l))
result = [list(i) for i in split_list if i]
print(result) # [['a', 'b'], ['c', 'd', 'b'], ['e', 'r']]