В python, как разрезать список по конкретному элементу? - PullRequest
0 голосов
/ 25 декабря 2018

Я пытаюсь вырезать список по определенным элементам в нем, например, у меня есть список вроде этого:

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'

Я не могу понятьчто не так.

Ответы [ 8 ]

0 голосов
/ 25 декабря 2018

Вы можете создать список индексов, затем использовать понимание списка:

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'.Это двухпроходное решение, но использует нарезку списка вместо явного добавления элементов по одному.

0 голосов
/ 25 декабря 2018
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']]
0 голосов
/ 25 декабря 2018

Каким был бы такой вопрос без ответа 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'))]
0 голосов
/ 25 декабря 2018

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)
0 голосов
/ 25 декабря 2018
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']
0 голосов
/ 25 декабря 2018
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)
0 голосов
/ 25 декабря 2018
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']]
0 голосов
/ 25 декабря 2018

Вы можете выполнить итерации своего оригинала и собрать подсписки во втором списке:

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, поэтому он имеетхуже, чем просто повторять список один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...