2012-04-09 31 views
5

Xác định quy trình, cùng một cấu trúc, có hai đầu vào. Nó sẽ xuất ra True nếu danh sách có cùng cấu trúc và False nếu không. Hai giá trị, p và q có cấu trúc tương tự nếu:Làm thế nào để tìm ra hai danh sách có cùng cấu trúc trong python?

Neither p or q is a list. 

Both p and q are lists, they have the same number of elements, and each 
element of p has the same structure as the corresponding element of q. 

EDIT: Để làm cho hình ảnh rõ ràng đây là các kết quả mong muốn

same_structure([1, 0, 1], [2, 1, 2]) 
    ---> True 
same_structure([1, [0], 1], [2, 5, 3]) 
    ---> False 
same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['d', 'e']]]]) 
    ---> True 
same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['de']]]]) 
    ---> False 

Tôi nghĩ đệ quy sẽ là tốt nhất để giải quyết vấn đề này trong python Tôi đã đưa ra mã sau nhưng nó không hoạt động.

def is_list(p): 
    return isinstance(p, list) 

def same_structure(a,b): 
    if not is_list(a) and not is_list(b): 
     return True 
    elif is_list(a) and is_list(b): 
     if len(a) == len(b): 
      same_structure(a[1:],b[1:]) 
    else: 
     return False 
+0

@SvenMarnach: trừ khi tôi đang đọc sai câu hỏi, [2, (3,4)] và [2, (5,)] có cùng cấu trúc: cả hai danh sách đều giống nhau số phần tử, và mỗi phần tử của p có cấu trúc giống như phần tử tương ứng của q vì không phải là một danh sách. IOW nó chỉ là cấu trúc danh sách quan trọng, các giá trị không (để [2] và [3] có cấu trúc giống nhau.) – DSM

+1

Xác định "cấu trúc giống nhau" cho một danh sách như cho python ['a', '1 '] không bằng [' 1 ',' a ']. Có lẽ bạn cũng nên sử dụng các bộ. – KurzedMetal

+0

Trong ngữ cảnh này mặc dù tôi nghĩ rằng tôi * sẽ * nói rằng chúng chứa các phần tử giống nhau, trong đó bình đẳng được xác định bởi quan hệ đã cho. Tôi nghĩ rằng tôi đã có một câu hỏi như thế này bản thân mình, trở lại trong ngày. – DSM

Trả lời

3

Recursion sẽ là một ý tưởng tốt, nhưng không phải là cách bạn đã gợi ý nó. Trước hết (và điều này có thể chỉ là lỗi đánh máy), bạn không thực sự trả lại bất cứ điều gì ở đây:

if len(a) == len(b): 
    same_structure(a[1:],b[1:]) 

Thứ hai, bạn nên đệ quy xử lý từng phần tử chứ không phải từng danh sách con. tức là .:

if len(a) == len(b): 
    for i in range(len(a)): 
     if not same_structure(a[i], b[i]): 
      return False 
    return True 
else: 
    return False 

Hy vọng điều này sẽ hữu ích.

5

Bạn đang thiếu một trường hợp và quên quay lại trong trường hợp thứ hai. Lưu ý rằng không cần phải so sánh rõ ràng độ dài của danh sách, vì trường hợp đầu tiên quan tâm đến điều này - nếu một trong các danh sách trống và danh sách kia không, đó là vì một danh sách có ít phần tử hơn so với một danh sách khác:

def same_structure(a, b): 
    if a == [] or b == []: # one of the lists is empty 
     return a == b  # are both of the lists empty? 
    elif is_list(a[0]) != is_list(b[0]): 
     return False  # one of the elements is a list and the other is not 
    elif not is_list(a[0]): # neither element is a list 
     return same_structure(a[1:], b[1:]) 
    else:     # both elements are lists 
     return same_structure(a[0], b[0]) and same_structure(a[1:], b[1:]) 
+0

Cảm ơn câu trả lời nhưng nó không hoạt động vì so sánh số nguyên trong điều kiện thứ hai – u449355

+0

Vui lòng xem kết quả mong đợi trong câu hỏi mà bạn sẽ hiểu. – u449355

+0

@UmeshKacha điều kiện thứ hai ?, bạn là người đàn ông này: 'is_list (a [0])! = Is_list (b [0])'. Đó không phải là một so sánh số nguyên, nó là một so sánh boolean.Những gì mà dòng nói là: "nếu một trong những yếu tố là một danh sách và khác không phải là một danh sách, sau đó trở về False, bởi vì cấu trúc là khác nhau" –

5

Thay vì same_structure(a[1:],b[1:]), bạn cần phải kiểm tra cặp mục của a và b từng người một

def is_list(p): 
    return isinstance(p, list) 

def same_structure(a, b): 
    if not is_list(a) and not is_list(b): 
     return True 
    elif (is_list(a) and is_list(b)) and (len(a) == len(b)): 
     return all(map(same_structure, a, b)) # Here 
    return False 
1

Kể từ khi đặc điểm kỹ thuật nói rằng các đầu vào là hai danh sách, bạn có thể lặp lại danh sách bên trong chức năng của bạn mà không có thêm kiểm tra và chỉ thực hiện các cuộc gọi đệ quy nếu bạn gặp phải các danh sách con:

def same_structure(a, b): 
    if len(a) != len(b): 
     return False 
    return all(is_list(x) and is_list(y) and same_structure(x, y) or 
       not is_list(x) and not is_list(y) 
       for x, y in zip(a, b)) 
0

Bạn có thể thử cách này quá cũng có, kiểm tra các loại cả hai danh sách & chiều dài của cả hai danh sách và thực hiện điều này một cách đệ quy cho phụ danh sách của cả hai danh sách.

def same_structure(a,b): 
    return isinstance(a, list) and isinstance(b, list) and len(a) == len(b) 
    and all(same_structure_as(c, d) for c, d in zip(a, b) if isinstance(c, list)) 
+0

Trong khi mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về cách thức và/hoặc lý do giải thích vấn đề này sẽ cải thiện giá trị lâu dài của câu trả lời. –

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