2013-08-04 66 views
5

Tôi có danh sách 2D, ví dụ mylist =[[1,2,3],[4,5,6],[7,8,9]].Độ dài của danh sách 2d trong python

Có cách nào để tôi có thể sử dụng chức năng len() sao cho tôi có thể tính toán độ dài của chỉ mục mảng không? Ví dụ:

len(mylist[0:3]) 
len(mylist[1:3]) 
len(mylist[0:1]) 

nên cung cấp cho:

9 
6 
3 

Trả lời

4

length = sum([len(arr) for arr in mylist])

sum([len(arr) for arr in mylist[0:3]]) = 9 
sum([len(arr) for arr in mylist[1:3]]) = 6 
sum([len(arr) for arr in mylist[2:3]]) = 3 

Sum chiều dài của eac danh sách h trong mylist để nhận độ dài của tất cả các phần tử.
Điều này sẽ chỉ hoạt động chính xác nếu danh sách là 2D. Nếu một số yếu tố của mylist không danh sách, ai mà biết được điều gì sẽ xảy ra ...

Ngoài ra, bạn có thể liên kết này để một hàm:

len2 = lambda l: sum([len(x) for x in l]) 
len2(mylist[0:3]) = 9 
len2(mylist[1:3]) = 6 
len2(mylist[2:3]) = 3 
+2

Không cần phải sử dụng danh sách hiểu. Một máy phát nhanh hơn. – Blender

+0

Hơn là hiểu danh sách? Tôi có một thời gian khó tin rằng ... –

+1

@MattBryant Tất nhiên. 'sum (len (arr) cho arr trong danh sách của tôi [0: 3])' là nhanh hơn 'tổng ([len (arr) cho arr trong danh sách của tôi [0: 3]])' – TerryA

2

Bạn có thể san bằng danh sách, sau đó gọi len vào nó:

>>> mylist=[[1,2,3],[4,5,6],[7,8,9]] 
>>> import collections 
>>> def flatten(l): 
...  for el in l: 
...   if isinstance(el, collections.Iterable) and not isinstance(el, basestring): 
...    for sub in flatten(el): 
...     yield sub 
...   else: 
...    yield el 
... 
>>> len(list(flatten(mylist))) 
9 
>>> len(list(flatten(mylist[1:3]))) 
6 
>>> len(list(flatten(mylist[0:1]))) 
3 
0

thế nào về len(ast.flatten(lst))? chỉ hoạt động trong py2k afaik

Đó là

from compiler import ast 
len(ast.flatten(lst)) 

từ

ast.flatten([1,2,3]) == [1,2,3] 
ast.flatten(mylist[0:2]) == [1,2,3,4,5,6] 
ast.flatten(mylist) == [1,2,3,4,5,6,7,8,9] 
2

Bạn có thể sử dụng reduce để tính toán chiều dài của chỉ số mảng như thế này, điều này cũng có thể xử lý các tình huống khi bạn vượt qua trong một cái gì đó như mylist[0:0]:

def myLen(myList): 
    return reduce(lambda x, y:x+y, [len(x) for x in myList], 0) 

myLen(mylist[0:3]) = 9 
myLen(mylist[1:3]) = 6 
myLen(mylist[0:1]) = 3 
myLen(mylist[0:0]) = 0 
2

Tôi thích @Ha câu trả lời của idro, mà làm việc cho tùy ý làm tổ, nhưng tôi không thích việc tạo ra các danh sách trung gian. Đây là một biến thể tránh điều đó.

try: 
    reduce 
except NameError: 
    # python3 - reduce is in functools, there is no basestring 
    from functools import reduce 
    basestring = str 

import operator 
import collections 

def rlen(item): 
    """ 
    rlen - recursive len(), where the "length" of a non-iterable 
    is just 1, but the length of anything else is the sum of the 
    lengths of its sub-items. 
    """ 
    if isinstance(item, collections.Iterable): 
     # A basestring is an Iterable that contains basestrings, 
     # i.e., it's endlessly recursive unless we short circuit 
     # here. 
     if isinstance(item, basestring): 
      return len(item) 
     return reduce(operator.add, (rlen(x) for x in item), 0) 
    return 1 

Vì tôi cũng đã bao gồm máy phát điện, hoàn toàn đệ quy flatten. Lưu ý rằng thời gian này có một quyết định khó khăn hơn để thực hiện về chuỗi (ngắn mạch trên là tầm thường đúng kể từ khi len(some_string) == sum(len(char) for char in some_string)).

def flatten(item, keep_strings=False): 
    """ 
    Recursively flatten an iterable into a series of items. If given 
    an already flat item, just returns it. 
    """ 
    if isinstance(item, collections.Iterable): 
     # We may want to flatten strings too, but when they're 
     # length 1 we have to terminate recursion no matter what. 
     if isinstance(item, basestring) and (len(item) == 1 or keep_strings): 
      yield item 
     else: 
      for elem in item: 
       for sub in flatten(elem, keep_strings): 
        yield sub 
    else: 
     yield item 

Nếu bạn không cần phải tùy ý làm tổ-nếu bạn luôn chắc chắn rằng đây chỉ là một danh sách liệt kê (hoặc danh sách các hàng, tuple của danh sách, vv) -the phương pháp "tốt nhất" có lẽ là biến thể đơn giản "tổng của máy phát điện" của câu trả lời của @Matt Bryant:

len2 = lambda lst: sum(len(x) for x in lst) 
Các vấn đề liên quan