2015-05-17 21 views
13

tôi bị mắc kẹt tìm này ra và tự hỏi nếu có ai có thể chỉ cho tôi đi đúng hướng ...Python - Tìm giá trị như nhau trong một danh sách và nhóm lại với nhau một danh sách mới

Từ danh sách này:

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 

tôi đang cố gắng để tạo ra:

L = [[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]] 

Bất kỳ giá trị mà được tìm thấy là giống nhau được nhóm lại thành sublist riêng của nó. Đây là nỗ lực của tôi cho đến nay, tôi nghĩ tôi nên sử dụng vòng lặp while?

global n 

n = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] #Sorted list 
l = [] #Empty list to append values to 

def compare(val): 
    """ This function receives index values 
    from the n list (n[0] etc) """ 

    global valin 
    valin = val 

    global count 
    count = 0 

    for i in xrange(len(n)): 
     if valin == n[count]: # If the input value i.e. n[x] == n[iteration] 
      temp = valin, n[count] 
      l.append(temp) #append the values to a new list 
      count +=1 
     else: 
      count +=1 


for x in xrange (len(n)): 
    compare(n[x]) #pass the n[x] to compare function 
+0

* Đây là nỗ lực của tôi cho đến nay * ... Vui lòng đề cập đến nếu bạn gặp phải bất kỳ sự cố nào với mã của mình. –

+0

Tại sao lưu trữ tất cả các số? Tại sao không chỉ thu gọn nó vào một danh sách các bộ chứa hai giá trị. Số chính nó và số lần con số đó xảy ra. –

Trả lời

12

Có người đề cập đến cho N=[1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1] nó sẽ nhận được [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]]

Nói cách khác, khi số lượng danh sách không phải là theo thứ tự hoặc nó là một danh sách lộn xộn, nó không có sẵn.

Vì vậy, tôi có câu trả lời tốt hơn để giải quyết vấn đề này.

from collections import Counter 

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 
C = Counter(N) 

print [ [k,]*v for k,v in C.items()] 
+0

Fantastic Tony! Tôi đã chạy vào các vấn đề với lập chỉ mục bằng cách sử dụng các giải pháp itertools để phương pháp này làm việc tốt như tôi không cần phải sắp xếp danh sách trước khi tay! Cảm ơn bạn một lần nữa! – Siii

3

Bạn đang quá phức tạp điều này.

Điều bạn muốn làm là: đối với mỗi giá trị, nếu giá trị đó giống với giá trị cuối cùng, chỉ cần nối nó vào danh sách giá trị cuối cùng; nếu không, hãy tạo một danh sách mới. Bạn có thể dịch rằng tiếng Anh trực tiếp đến Python:

new_list = [] 
for value in old_list: 
    if new_list and new_list[-1][0] == value: 
     new_list[-1].append(value) 
    else: 
     new_list.append([value]) 

Có nhiều cách đơn giản hơn để làm điều này nếu bạn sẵn sàng để có được một chút trừu tượng hơn, ví dụ, bằng cách sử dụng các chức năng nhóm trong itertools. Nhưng điều này phải dễ hiểu.


Nếu bạn thực sự cần phải làm điều này với một vòng lặp while, bạn có thể dịch bất kỳ for vòng thành một vòng lặp while như thế này:

for value in iterable: 
    do_stuff(value) 

iterator = iter(iterable) 
while True: 
    try: 
     value = next(iterator) 
    except StopIteration: 
     break 
    do_stuff(value) 

Hoặc, nếu bạn biết iterable là một chuỗi, bạn có thể sử dụng một chút đơn giản while loop:

index = 0 
while index < len(sequence): 
    value = sequence[index] 
    do_stuff(value) 
    index += 1 

Nhưng cả hai làm cho mã của bạn dễ đọc hơn, ít Pythonic, phức tạp hơn, kém hiệu quả, dễ dàng hơn để có được sai vv

+0

Câu trả lời thực sự hay (tôi thích sức mạnh vũ phu), Nhưng bạn có thể nghĩ ra cách sử dụng vòng lặp 'while' không? Trong các từ của OP * Tôi nghĩ rằng tôi nên sử dụng một vòng lặp while? * –

+2

@BhargavRao: Vâng, bạn luôn có thể dịch bất kỳ vòng lặp 'for' nào thành một vòng lặp' while'. Nhưng tại sao bạn muốn? – abarnert

+0

Đối với vấn đề này, vòng lặp 'for' phù hợp hơn. Không giống như C, bản dịch py không thẳng thắn, mặc dù chúng khá dễ dàng. Tôi chỉ yêu cầu cung cấp cho OP một ý tưởng hợp lý về vòng lặp 'while' và đó là những biến chứng. Đừng xem xét việc làm rằng trong thời gian rảnh rỗi của bạn Vâng tốt ai ở đó :) –

3

Bạn có thể sử dụng itertools.groupby cùng với một list comprehension

>>> l = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 
>>> [list(v) for k,v in itertools.groupby(l)] 
[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 

này có thể được gán vào biến L như trong

L = [list(v) for k,v in itertools.groupby(l)] 
26

Giữ bình tĩnh và sử dụng itertools.groupby:

from itertools import groupby 

N = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5] 

print([list(j) for i, j in groupby(N)]) 

Output:

[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 

Side lưu ý: Ngăn chặn từ việc sử dụng biến toàn cầu khi bạn không cần tới.

+0

Lưu ý: danh sách cần phải được sắp xếp theo cùng một chìa khóa được sử dụng bởi groupby để đạt được kết quả mong đợi trong câu hỏi. Nếu không, ví dụ: cho 'N = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1]' bạn sẽ nhận được '[[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5], [1]] '. –

-1

Một giải pháp hơi khác nhau mà không dựa vào itertools:

#!/usr/bin/env python 

def group(items): 
    """ 
    groups a sorted list of integers into sublists based on the integer key 
    """ 
    if len(items) == 0: 
     return [] 

    grouped_items = [] 
    prev_item, rest_items = items[0], items[1:] 

    subgroup = [prev_item] 
    for item in rest_items: 
     if item != prev_item: 
      grouped_items.append(subgroup) 
      subgroup = [] 
     subgroup.append(item) 
     prev_item = item 

    grouped_items.append(subgroup) 
    return grouped_items 

print group([1,2,2,3,3,3,4,4,4,4,5,5,5,5,5]) 
# [[1], [2, 2], [3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5, 5]] 
Các vấn đề liên quan