2010-07-12 69 views
6

Trong trăn, làm cách nào tôi có thể chia danh sách dài thành danh sách các danh sách bất cứ nơi nào tôi gặp '-'. Ví dụ, làm thế nào tôi có thể chuyển đổi:danh sách> danh sách các danh sách

['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 

để

[['1', 'a', 'b'],['2','c','d'],['3','123','e'],['4']] 

Nhiều cảm ơn trước.

Trả lời

17
In [17]: import itertools 
# putter around 22 times 
In [39]: l=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 

In [40]: [list(g) for k,g in itertools.groupby(l,'---'.__ne__) if k] 
Out[40]: [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
+0

+1 Nice (không nghĩ ngay đến 'itertools.groupby' ở đây nhưng nó phù hợp với hóa đơn thực sự) – ChristopheD

+0

Cảm ơn câu trả lời của bạn. Có cách nào để kiểm tra x == '---' trong dòng trên với một biểu thức chính quy (một cái gì đó như x == re.match ('-'))? Rất cám ơn – DGT

+0

Vâng, bạn có thể sử dụng một cái gì đó như '[danh sách (g) cho k, g trong itertools.groupby (l, lambda x: re.match ('---', x)) nếu không k]'. Biểu thức 're.match (...)' trả về None khi 'x' không khớp với mẫu. Do đó 'k' là' None' cho các phần tử bạn muốn giữ lại. Vì vậy, tôi đã thay đổi điều kiện thành 'if not k'. – unutbu

4
import itertools 

l = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
r = [] 

i = iter(l) 
while True: 
    a = [x for x in itertools.takewhile(lambda x: x != '---', i)] 
    if not a: 
    break 
    r.append(a) 
print r 

# [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
+0

+1 Tôi thích điều này tốt hơn thì giải pháp tương tự của tôi (sẽ xóa nó ngay) vì cách tiếp cận 'lặp lại 'hiệu quả (chỉ tiêu thụ nó một lần). Nhưng bạn có thể muốn thay thế 'cho j trong phạm vi (7)' bằng 'trong khi True' để xử lý các độ dài tùy ý. – ChristopheD

+0

@ChristopheD: Có, đã sửa. –

-1

Nó được một lúc kể từ khi tôi đã thực hiện bất kỳ python nên cú pháp của tôi sẽ là con đường tắt, nhưng một vòng lặp đơn giản là đủ.

theo dõi các chỉ số trong hai số

firstList = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
listIndex = 0 
itemIndex = 0 
ii = 0 
foreach item in firstList 
    if(firstList[ii] == '---') 
    listIndex = listIndex + 1 
    itemIndex = 0 
    ii = ii + 1 
    else secondList[listIndex][itemIndex] = firstList[ii] 
1
import itertools 

a = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
b = [list(x[1]) for x in itertools.groupby(a, '---'.__eq__) if not x[0]] 

print b  # or print(b) in Python 3 

Kết quả là

[['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']] 
0

Dưới đây là một giải pháp mà không itertools:

def foo(input): 
    output = [] 
    currentGroup = [] 
    for value in input: 
     if '-' in value: #if we should break on this element 
      currentGroup.append(value) 
     elif currentGroup: 
      output.append(currentGroup) 
      currentGroup = [] 
    if currentGroup: 
     output.append(currentGroup) #appends the rest if not followed by separator  
    return output 

print (foo (['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'])) 
+1

Ngoài một ngưỡng nhất định, khả năng đọc là tương đối. Điều đó trông giống như một khối mã lớn với tôi. –

+1

Sử dụng (1) 'value.find ('-') == -1' thay vì' '-' trong giá trị' (2) camelCase (2) dấu ngoặc đơn thừa trong '(el) nếu' đôi khi (3) các khoảng cách không liên quan bên trong dấu ngoặc đơn đôi khi (4) tuyên bố đủ lâu để làm cho SO chèn thanh cuộn ngang ferschlugginer (5) không có dấu cách sau dấu phẩy đôi khi làm cho nó trông giống như một mớ hỗn độn lớn của mã fugly cho tôi. –

+0

Cả hai đều đúng. Đã chỉnh sửa mã và mô tả. :) –

1

Dưới đây là một cách để làm điều đó :

lst=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] 
indices=[-1]+[i for i,x in enumerate(lst) if x=='---']+[len(lst)] 
answer=[lst[indices[i-1]+1:indices[i]] for i in xrange(1,len(indices))] 
print answer 

Về cơ bản, điều này sẽ tìm vị trí của chuỗi '---' trong danh sách và sau đó cắt danh sách tương ứng.

Các vấn đề liên quan