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)
Không cần phải sử dụng danh sách hiểu. Một máy phát nhanh hơn. – Blender
Hơn là hiểu danh sách? Tôi có một thời gian khó tin rằng ... –
@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